fix: refresh favorite identity from market bridge

This commit is contained in:
wxs
2026-07-17 16:54:19 +08:00
parent ddf9a75e82
commit 9ed2c23230
2 changed files with 33 additions and 12 deletions
+30 -1
View File
@@ -138,6 +138,7 @@ export interface CreateMarketControllerOptions {
const AUDIENCE_PROFILE_FIELD_SELECTION_STORAGE_KEY = const AUDIENCE_PROFILE_FIELD_SELECTION_STORAGE_KEY =
"sces:audience-profile:selectedHeaders"; "sces:audience-profile:selectedHeaders";
const SERIALIZED_MARKET_ROWS_ATTRIBUTE = "data-sces-market-rows";
export function createMarketController(options: CreateMarketControllerOptions) { export function createMarketController(options: CreateMarketControllerOptions) {
const marketApiClient = createMarketApiClient(); const marketApiClient = createMarketApiClient();
@@ -226,6 +227,7 @@ export function createMarketController(options: CreateMarketControllerOptions) {
let activeSort: MarketSortState | undefined; let activeSort: MarketSortState | undefined;
let isDisposed = false; let isDisposed = false;
let lastKnownPageSignature = ""; let lastKnownPageSignature = "";
let lastKnownFavoriteIdentitySignature = readFavoriteIdentitySignature(options.document);
let needsResync = false; let needsResync = false;
let scheduledSyncTimeoutId: number | null = null; let scheduledSyncTimeoutId: number | null = null;
let activeSyncPromise: Promise<void> | null = null; let activeSyncPromise: Promise<void> | null = null;
@@ -268,6 +270,9 @@ export function createMarketController(options: CreateMarketControllerOptions) {
} catch { } catch {
return; return;
} }
const nextFavoriteIdentitySignature = readFavoriteIdentitySignature(options.document);
const favoriteIdentityChanged =
nextFavoriteIdentitySignature !== lastKnownFavoriteIdentitySignature;
const toolbarNeedsRemount = const toolbarNeedsRemount =
!toolbar || !isPluginToolbarMounted(toolbar.root, options.document); !toolbar || !isPluginToolbarMounted(toolbar.root, options.document);
@@ -291,7 +296,8 @@ export function createMarketController(options: CreateMarketControllerOptions) {
!needsToolbarRemount && !needsToolbarRemount &&
!selectionControlsMissing && !selectionControlsMissing &&
!favoriteControlsMissing && !favoriteControlsMissing &&
!needsUnavailableFavoritesRecovery !needsUnavailableFavoritesRecovery &&
!favoriteIdentityChanged
) { ) {
return; return;
} }
@@ -303,6 +309,10 @@ export function createMarketController(options: CreateMarketControllerOptions) {
if (favoriteControlsMissing || needsUnavailableFavoritesRecovery) { if (favoriteControlsMissing || needsUnavailableFavoritesRecovery) {
needsFavoritesRefresh = true; needsFavoritesRefresh = true;
} }
if (favoriteIdentityChanged) {
lastKnownFavoriteIdentitySignature = nextFavoriteIdentitySignature;
needsFavoritesRefresh = true;
}
scheduleSync(); scheduleSync();
}); });
const observationRoot = options.document.body ?? options.document.documentElement; const observationRoot = options.document.body ?? options.document.documentElement;
@@ -1870,10 +1880,25 @@ export function createMarketController(options: CreateMarketControllerOptions) {
return; return;
} }
const documentElement = options.document.documentElement;
if (observationRoot === documentElement) {
observer.observe(observationRoot, {
attributeFilter: [SERIALIZED_MARKET_ROWS_ATTRIBUTE],
attributes: true,
childList: true,
subtree: true
});
return;
}
observer.observe(observationRoot, { observer.observe(observationRoot, {
childList: true, childList: true,
subtree: true subtree: true
}); });
observer.observe(documentElement, {
attributeFilter: [SERIALIZED_MARKET_ROWS_ATTRIBUTE],
attributes: true
});
} }
function runSyncCycle(): Promise<void> { function runSyncCycle(): Promise<void> {
@@ -1929,6 +1954,10 @@ export function createMarketController(options: CreateMarketControllerOptions) {
} }
function readFavoriteIdentitySignature(document: Document): string {
return document.documentElement.getAttribute(SERIALIZED_MARKET_ROWS_ATTRIBUTE) ?? "";
}
function readNativeToolbarActionCount(document: Document): number { function readNativeToolbarActionCount(document: Document): number {
return Array.from(document.querySelectorAll("button, a, [role='button']")).filter( return Array.from(document.querySelectorAll("button, a, [role='button']")).filter(
(element) => { (element) => {
+3 -11
View File
@@ -4658,8 +4658,8 @@ describe("market-content-entry", () => {
}); });
test("preserves a late serialized core user id through favorite batch import", async () => { test("preserves a late serialized core user id through favorite batch import", async () => {
document.body.innerHTML = buildRealMarketFixtureWithoutAuthorIds([ document.body.innerHTML = buildRealMarketFixture([
{ authorName: "达人 A", price21To60s: "¥11,000" } { authorId: "111", authorName: "达人 A", price21To60s: "¥11,000" }
]); ]);
const repository = createTestFavoritesRepository(); const repository = createTestFavoritesRepository();
const observer = createMutationObserverFactory(); const observer = createMutationObserverFactory();
@@ -4687,16 +4687,8 @@ describe("market-content-entry", () => {
{ authorId: "111", authorName: "达人 A", coreUserId: "core-111" } { authorId: "111", authorName: "达人 A", coreUserId: "core-111" }
]) ])
); );
document.documentElement.setAttribute("data-test-page-index", "2");
observer.trigger(); observer.trigger();
await waitForCondition( await flushWithTimers();
() => {
const favoriteButton = document.querySelector(
'[data-sces-favorite-row-action="button"]'
);
return favoriteButton instanceof HTMLButtonElement && !favoriteButton.disabled;
}
);
click('[data-sces-favorite-row-action="button"]'); click('[data-sces-favorite-row-action="button"]');
click('[data-sces-favorite-row-picker="create-folder"]'); click('[data-sces-favorite-row-picker="create-folder"]');