mirror of
https://github.com/GopeedLab/gopeed.git
synced 2026-11-06 00:25:43 +00:00
Merge latest main into 2.0.0-beta.2
# Conflicts: # internal/webview/README.md # ui/flutter/lib/app/rpc/webview_rpc_service.dart # ui/flutter/pubspec.lock # ui/flutter/pubspec.yaml
This commit is contained in:
commit
88dd35cc46
7 files changed
+185
-32
No files matched your search
@@ -3,7 +3,10 @@
|
||||
The downloader wraps each provider with the extension's stable identity before
|
||||
constructing the runtime. `OpenOptions.ProfileID`, `DataPath`, and `ProxyURL` are
|
||||
host-only fields. `parseOpenOptions` never reads them from extension JavaScript.
|
||||
The extension API is unchanged.
|
||||
The extension API is unchanged. The Flutter host uses the fork's public
|
||||
`WebViewProfile`, `InAppWebViewSettings.profileId`, and profile-scoped
|
||||
`CookieManager` APIs; the library has no Gopeed-specific method-channel bridge.
|
||||
Only the Gopeed extension JavaScript boundary keeps these options host-only.
|
||||
|
||||
Profiles are persistent and shared across invocations/pages of the same extension.
|
||||
Different identities use different native stores. Go providers use a SHA-256-based
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# rpcprovider
|
||||
|
||||
The private Flutter native profile bridge is maintained in the
|
||||
[GopeedLab flutter_inappwebview fork](https://github.com/GopeedLab/flutter_inappwebview/tree/codex/gopeed-profiles).
|
||||
All three platform overrides pin one commit in `ui/flutter/pubspec.yaml`;
|
||||
see the fork’s [GOPEED.md](https://github.com/GopeedLab/flutter_inappwebview/blob/codex/gopeed-profiles/GOPEED.md)
|
||||
for patch scope and upstream synchronization.
|
||||
|
||||
`rpcprovider` is the RPC-backed implementation of Gopeed's `webview.Provider` interface.
|
||||
|
||||
It is intended for environments where WebView capability is owned by another process, most notably mobile hosts. This package does not implement a WebView itself. Instead, it translates the `pkg/download/engine/webview` page API into single-request `POST + JSON` calls sent to a local host-side RPC service.
|
||||
|
||||
@@ -32,6 +32,7 @@ final class GopeedContinuedProcessingManager: NSObject {
|
||||
private var expiringTasks:
|
||||
[String: ExpiringTaskState] = [:]
|
||||
private var taskGenerations: [String: UUID] = [:]
|
||||
private var progressRecoveryTokens: [String: UUID] = [:]
|
||||
|
||||
private var activeTasks:
|
||||
[String: BGContinuedProcessingTask] = [:]
|
||||
@@ -224,6 +225,10 @@ final class GopeedContinuedProcessingManager: NSObject {
|
||||
switch type {
|
||||
|
||||
case "task.start":
|
||||
progressRecoveryTokens.removeValue(
|
||||
forKey: taskID
|
||||
)
|
||||
|
||||
beginTask(
|
||||
taskID: taskID,
|
||||
name: name
|
||||
@@ -237,6 +242,11 @@ final class GopeedContinuedProcessingManager: NSObject {
|
||||
generation: generation,
|
||||
force: false
|
||||
)
|
||||
} else {
|
||||
recoverTaskFromProgress(
|
||||
taskID: taskID,
|
||||
name: name
|
||||
)
|
||||
}
|
||||
|
||||
case "task.pause":
|
||||
@@ -285,6 +295,72 @@ final class GopeedContinuedProcessingManager: NSObject {
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Recover active task after setting changes
|
||||
|
||||
private func recoverTaskFromProgress(
|
||||
taskID: String,
|
||||
name: String
|
||||
) {
|
||||
guard
|
||||
currentEnabledSnapshot(),
|
||||
taskGenerations[taskID] == nil,
|
||||
!pendingTaskIDs.contains(taskID),
|
||||
activeTasks[taskID] == nil,
|
||||
expiringTasks[taskID] == nil,
|
||||
progressRecoveryTokens[taskID] == nil
|
||||
else {
|
||||
return
|
||||
}
|
||||
|
||||
let recoveryToken = UUID()
|
||||
|
||||
progressRecoveryTokens[taskID] =
|
||||
recoveryToken
|
||||
|
||||
getRuntimeStatus(
|
||||
taskID: taskID
|
||||
) { [weak self] runtime in
|
||||
guard
|
||||
let self,
|
||||
self.progressRecoveryTokens[taskID]
|
||||
== recoveryToken
|
||||
else {
|
||||
return
|
||||
}
|
||||
|
||||
// The status request has completed. Remove the token so
|
||||
// another progress event may retry if recovery is still
|
||||
// necessary.
|
||||
self.progressRecoveryTokens.removeValue(
|
||||
forKey: taskID
|
||||
)
|
||||
|
||||
guard
|
||||
self.currentEnabledSnapshot(),
|
||||
let runtime,
|
||||
runtime.status == "running",
|
||||
self.taskGenerations[taskID] == nil,
|
||||
!self.pendingTaskIDs.contains(taskID),
|
||||
self.activeTasks[taskID] == nil,
|
||||
self.expiringTasks[taskID] == nil
|
||||
else {
|
||||
return
|
||||
}
|
||||
|
||||
print(
|
||||
"ContinuedProcessing:",
|
||||
"recovering active task:",
|
||||
taskID
|
||||
)
|
||||
|
||||
self.beginTask(
|
||||
taskID: taskID,
|
||||
name: name
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Used by Objective-C forwarder
|
||||
|
||||
@objc(isHandlingTaskId:)
|
||||
@@ -825,6 +901,10 @@ final class GopeedContinuedProcessingManager: NSObject {
|
||||
success: Bool,
|
||||
finalSubtitle: String
|
||||
) {
|
||||
progressRecoveryTokens.removeValue(
|
||||
forKey: taskID
|
||||
)
|
||||
|
||||
taskGenerations.removeValue(
|
||||
forKey: taskID
|
||||
)
|
||||
@@ -1063,6 +1143,7 @@ final class GopeedContinuedProcessingManager: NSObject {
|
||||
pendingTaskIDs.removeAll()
|
||||
expiringTasks.removeAll()
|
||||
taskGenerations.removeAll()
|
||||
progressRecoveryTokens.removeAll()
|
||||
taskIdentifiers.removeAll()
|
||||
taskNames.removeAll()
|
||||
lastProgressUpdate.removeAll()
|
||||
|
||||
@@ -108,6 +108,39 @@ final class GopeedLiveActivityManager: NSObject {
|
||||
return generation
|
||||
}
|
||||
|
||||
private func generationForProgress(
|
||||
taskID: String
|
||||
) -> UUID? {
|
||||
stateLock.lock()
|
||||
defer { stateLock.unlock() }
|
||||
|
||||
guard
|
||||
!suppressedTaskIDs.contains(taskID)
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
|
||||
if let generation =
|
||||
taskGenerations[taskID] {
|
||||
return generation
|
||||
}
|
||||
|
||||
// Progress may be the first event after Continued Processing
|
||||
// releases ownership. Establish a fresh lifecycle generation.
|
||||
// refreshActivity still verifies that Gopeed reports the task
|
||||
// as running before it can create a Live Activity.
|
||||
let generation = UUID()
|
||||
|
||||
taskGenerations[taskID] =
|
||||
generation
|
||||
|
||||
lastUpdateTime.removeValue(
|
||||
forKey: taskID
|
||||
)
|
||||
|
||||
return generation
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
private func invalidateGeneration(
|
||||
taskID: String
|
||||
@@ -252,7 +285,7 @@ final class GopeedLiveActivityManager: NSObject {
|
||||
case "task.progress":
|
||||
guard
|
||||
let generation =
|
||||
currentGeneration(
|
||||
generationForProgress(
|
||||
taskID: taskID
|
||||
)
|
||||
else {
|
||||
|
||||
@@ -167,11 +167,11 @@ class WebViewRpcService {
|
||||
|
||||
Future<Map<String, dynamic>> _openPage(Map<String, dynamic> params) async {
|
||||
final profile = WebViewProfile(_string(params, 'profileId'));
|
||||
await profile.prepare(_string(params, 'proxyUrl'));
|
||||
await profile.prepare(proxyUrl: Uri.parse(_string(params, 'proxyUrl')));
|
||||
final pageId = 'page-${++_pageSeq}';
|
||||
final session = WebViewRpcPageSession(
|
||||
pageId: pageId,
|
||||
cookieManager: profile,
|
||||
profile: profile,
|
||||
headless: params['headless'] as bool? ?? false,
|
||||
debug: params['debug'] as bool? ?? false,
|
||||
title: params['title'] as String? ?? '',
|
||||
@@ -192,7 +192,7 @@ class WebViewRpcService {
|
||||
}
|
||||
|
||||
Future<void> _removeProfile(String id) async {
|
||||
for (final page in _pagesById.values.where((page) => page.cookieManager.id == id).toList()) {
|
||||
for (final page in _pagesById.values.where((page) => page.profile.id == id).toList()) {
|
||||
await _closePage(page.pageId);
|
||||
}
|
||||
// Let visible platform views unmount before releasing their native store.
|
||||
@@ -301,7 +301,7 @@ class WebViewRpcService {
|
||||
class WebViewRpcPageSession {
|
||||
WebViewRpcPageSession({
|
||||
required this.pageId,
|
||||
required this.cookieManager,
|
||||
required this.profile,
|
||||
required this.headless,
|
||||
required this.debug,
|
||||
required this.title,
|
||||
@@ -311,7 +311,8 @@ class WebViewRpcPageSession {
|
||||
});
|
||||
|
||||
final String pageId;
|
||||
final WebViewProfile cookieManager;
|
||||
final WebViewProfile profile;
|
||||
late final CookieManager cookieManager = profile.cookieManager;
|
||||
final bool headless;
|
||||
final bool debug;
|
||||
final String title;
|
||||
@@ -543,9 +544,11 @@ class WebViewRpcPageSession {
|
||||
);
|
||||
}
|
||||
|
||||
InAppWebViewSettings get _settings => WebViewProfileSettings(
|
||||
profileId: cookieManager.id,
|
||||
debug: debug,
|
||||
InAppWebViewSettings get _settings => InAppWebViewSettings(
|
||||
profileId: profile.id,
|
||||
javaScriptEnabled: true,
|
||||
transparentBackground: true,
|
||||
isInspectable: debug,
|
||||
userAgent: userAgent.isNotEmpty ? userAgent : null,
|
||||
);
|
||||
|
||||
|
||||
+26
-18
@@ -457,17 +457,20 @@ packages:
|
||||
flutter_inappwebview:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_inappwebview
|
||||
sha256: "80092d13d3e29b6227e25b67973c67c7210bd5e35c4b747ca908e31eb71a46d5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
path: flutter_inappwebview
|
||||
ref: d579215760e1c1e58a4ff7601a6055b5e6adf8e8
|
||||
resolved-ref: d579215760e1c1e58a4ff7601a6055b5e6adf8e8
|
||||
url: "https://github.com/GopeedLab/flutter_inappwebview.git"
|
||||
source: git
|
||||
version: "6.1.5"
|
||||
flutter_inappwebview_android:
|
||||
dependency: "direct overridden"
|
||||
description:
|
||||
path: "third_party/flutter_inappwebview_android"
|
||||
relative: true
|
||||
source: path
|
||||
path: flutter_inappwebview_android
|
||||
ref: d579215760e1c1e58a4ff7601a6055b5e6adf8e8
|
||||
resolved-ref: d579215760e1c1e58a4ff7601a6055b5e6adf8e8
|
||||
url: "https://github.com/GopeedLab/flutter_inappwebview.git"
|
||||
source: git
|
||||
version: "1.1.3"
|
||||
flutter_inappwebview_internal_annotations:
|
||||
dependency: transitive
|
||||
@@ -480,24 +483,29 @@ packages:
|
||||
flutter_inappwebview_ios:
|
||||
dependency: "direct overridden"
|
||||
description:
|
||||
path: "third_party/flutter_inappwebview_ios"
|
||||
relative: true
|
||||
source: path
|
||||
path: flutter_inappwebview_ios
|
||||
ref: d579215760e1c1e58a4ff7601a6055b5e6adf8e8
|
||||
resolved-ref: d579215760e1c1e58a4ff7601a6055b5e6adf8e8
|
||||
url: "https://github.com/GopeedLab/flutter_inappwebview.git"
|
||||
source: git
|
||||
version: "1.1.2"
|
||||
flutter_inappwebview_macos:
|
||||
dependency: "direct overridden"
|
||||
description:
|
||||
path: "third_party/flutter_inappwebview_macos"
|
||||
relative: true
|
||||
source: path
|
||||
path: flutter_inappwebview_macos
|
||||
ref: d579215760e1c1e58a4ff7601a6055b5e6adf8e8
|
||||
resolved-ref: d579215760e1c1e58a4ff7601a6055b5e6adf8e8
|
||||
url: "https://github.com/GopeedLab/flutter_inappwebview.git"
|
||||
source: git
|
||||
version: "1.1.2"
|
||||
flutter_inappwebview_platform_interface:
|
||||
dependency: transitive
|
||||
dependency: "direct overridden"
|
||||
description:
|
||||
name: flutter_inappwebview_platform_interface
|
||||
sha256: cf5323e194096b6ede7a1ca808c3e0a078e4b33cc3f6338977d75b4024ba2500
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
path: flutter_inappwebview_platform_interface
|
||||
ref: d579215760e1c1e58a4ff7601a6055b5e6adf8e8
|
||||
resolved-ref: d579215760e1c1e58a4ff7601a6055b5e6adf8e8
|
||||
url: "https://github.com/GopeedLab/flutter_inappwebview.git"
|
||||
source: git
|
||||
version: "1.3.0+1"
|
||||
flutter_inappwebview_web:
|
||||
dependency: transitive
|
||||
|
||||
+23
-4
@@ -86,13 +86,32 @@ dependencies:
|
||||
go_router: ^16.2.1
|
||||
|
||||
dependency_overrides:
|
||||
# Host-only native WebView profile/proxy bridge.
|
||||
# Public persistent-profile and proxy APIs; keep all packages on one commit.
|
||||
flutter_inappwebview:
|
||||
git:
|
||||
url: https://github.com/GopeedLab/flutter_inappwebview.git
|
||||
ref: d579215760e1c1e58a4ff7601a6055b5e6adf8e8
|
||||
path: flutter_inappwebview
|
||||
flutter_inappwebview_platform_interface:
|
||||
git:
|
||||
url: https://github.com/GopeedLab/flutter_inappwebview.git
|
||||
ref: d579215760e1c1e58a4ff7601a6055b5e6adf8e8
|
||||
path: flutter_inappwebview_platform_interface
|
||||
flutter_inappwebview_macos:
|
||||
path: third_party/flutter_inappwebview_macos
|
||||
git:
|
||||
url: https://github.com/GopeedLab/flutter_inappwebview.git
|
||||
ref: d579215760e1c1e58a4ff7601a6055b5e6adf8e8
|
||||
path: flutter_inappwebview_macos
|
||||
flutter_inappwebview_ios:
|
||||
path: third_party/flutter_inappwebview_ios
|
||||
git:
|
||||
url: https://github.com/GopeedLab/flutter_inappwebview.git
|
||||
ref: d579215760e1c1e58a4ff7601a6055b5e6adf8e8
|
||||
path: flutter_inappwebview_ios
|
||||
flutter_inappwebview_android:
|
||||
path: third_party/flutter_inappwebview_android
|
||||
git:
|
||||
url: https://github.com/GopeedLab/flutter_inappwebview.git
|
||||
ref: d579215760e1c1e58a4ff7601a6055b5e6adf8e8
|
||||
path: flutter_inappwebview_android
|
||||
# Prevent a native Windows crash when the push notification service is unavailable.
|
||||
# Keep this fork until https://github.com/MaikuB/flutter_local_notifications/pull/2813 is merged and released.
|
||||
flutter_local_notifications:
|
||||
|
||||
Reference in new issue
Block a user