Skip to content

Commit e8b0dc1

Browse files
committed
Merge remote-tracking branch 'origin/main' into perf/search-list-violations-per-row
2 parents 856e976 + 3cf651b commit e8b0dc1

13 files changed

Lines changed: 50 additions & 55 deletions

File tree

src/components/Search/index.tsx

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,7 @@ function Search({
450450
// eslint-disable-next-line react-hooks/exhaustive-deps
451451
}, [isSmallScreenWidth]);
452452

453-
const {newSearchResultKeys, handleSelectionListScroll, newTransactions} = useSearchHighlightAndScroll({
453+
const {newSearchResultKeys, handleSelectionListScroll, newTransactions, hasQueuedHighlights} = useSearchHighlightAndScroll({
454454
searchResults,
455455
transactions,
456456
previousTransactions,
@@ -463,6 +463,16 @@ function Search({
463463
shouldUseLiveData,
464464
});
465465

466+
// Mirror `hasQueuedHighlights` into a ref so the post-create-flow `useFocusEffect`
467+
// (which has empty deps) can read the latest value without re-creating its callback.
468+
// Used to skip the deferral that would otherwise hide the freshly-added row from
469+
// FlashList during the RHP dismiss transition, which would prevent the highlight
470+
// animation from ever firing on it.
471+
const hasQueuedHighlightsRef = useRef(hasQueuedHighlights);
472+
useEffect(() => {
473+
hasQueuedHighlightsRef.current = hasQueuedHighlights;
474+
}, [hasQueuedHighlights]);
475+
466476
// There's a race condition in Onyx which makes it return data from the previous Search, so in addition to checking that the data is loaded
467477
// we also need to check that the searchResults matches the type and status of the current search
468478
const isDataLoaded = shouldUseLiveData || isSearchDataLoaded(searchResults, queryJSON);
@@ -518,6 +528,14 @@ function Search({
518528
return;
519529
}
520530

531+
// If the highlight hook already queued rows for the post-create animation,
532+
// skip the skeleton-during-transition defer. Otherwise FlashList stays empty
533+
// for ~1s while the RHP dismiss transition runs, the row never mounts inside
534+
// the 300ms highlight window, and `useAnimatedHighlightStyle` never fires.
535+
if (hasQueuedHighlightsRef.current) {
536+
return;
537+
}
538+
521539
// Show skeleton while the RHP dismiss animation plays. The transition
522540
// hasn't started yet when useFocusEffect fires (it begins after paint),
523541
// so waitForUpcomingTransition defers until the animation actually ends.

src/hooks/useSearchHighlightAndScroll.ts

Lines changed: 12 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import type {SearchKey} from '@libs/SearchUIUtils';
1414
import CONST from '@src/CONST';
1515
import ONYXKEYS from '@src/ONYXKEYS';
1616
import type {ReportActions, SearchResults, Transaction} from '@src/types/onyx';
17-
import {isEmptyObject} from '@src/types/utils/EmptyObject';
1817
import useNetwork from './useNetwork';
1918
import useOnyx from './useOnyx';
2019
import usePrevious from './usePrevious';
@@ -227,40 +226,23 @@ function useSearchHighlightAndScroll({
227226
}
228227

229228
const newKeys = new Set<string>();
229+
const consumedManualIDs: string[] = [];
230230
for (const id of newTransactionIDs) {
231231
const newTransactionKey = `${ONYXKEYS.COLLECTION.TRANSACTION}${id}`;
232232
highlightedIDs.current.add(newTransactionKey);
233233
newKeys.add(newTransactionKey);
234+
if (manualHighlightTransactionIDs.has(id)) {
235+
consumedManualIDs.push(id);
236+
}
234237
}
235238
setNewSearchResultKeys(newKeys);
236-
}
237-
}, [searchResults?.data, previousSearchResults, isChat, transactionIDsToHighlight]);
238239

239-
// Reset transactionIDsToHighlight after they have been highlighted
240-
useEffect(() => {
241-
if (isEmptyObject(transactionIDsToHighlight) || newSearchResultKeys === null) {
242-
return;
240+
// Clear consumed manual highlight flags so subsequent detect runs don't re-highlight the same IDs.
241+
if (consumedManualIDs.length > 0) {
242+
mergeTransactionIdsHighlightOnSearchRoute(queryJSON.type, Object.fromEntries(consumedManualIDs.map((id) => [id, false])));
243+
}
243244
}
244-
245-
const highlightedTransactionIDs = Object.keys(transactionIDsToHighlight).filter(
246-
(id) => transactionIDsToHighlight[id] && newSearchResultKeys?.has(`${ONYXKEYS.COLLECTION.TRANSACTION}${id}`),
247-
);
248-
249-
// We need to use requestAnimationFrame here to ensure that setTimeout actually starts
250-
// only after the user has navigated to the "Reports > Expenses" page.
251-
// Otherwise, there is still a chance we might miss the timing because setTimeout runs too early,
252-
// causing the highlight not to appear.
253-
let timer: NodeJS.Timeout;
254-
const animation = requestAnimationFrame(() => {
255-
timer = setTimeout(() => {
256-
mergeTransactionIdsHighlightOnSearchRoute(queryJSON.type, Object.fromEntries(highlightedTransactionIDs.map((id) => [id, false])));
257-
}, CONST.ANIMATED_HIGHLIGHT_START_DURATION);
258-
});
259-
return () => {
260-
clearTimeout(timer);
261-
cancelAnimationFrame(animation);
262-
};
263-
}, [transactionIDsToHighlight, queryJSON.type, newSearchResultKeys]);
245+
}, [searchResults?.data, previousSearchResults, isChat, transactionIDsToHighlight, queryJSON.type]);
264246

265247
// Remove transactionIDsToHighlight when the user leaves the current search type
266248
useEffect(
@@ -329,7 +311,9 @@ function useSearchHighlightAndScroll({
329311
triggeredByHookRef.current = false;
330312
};
331313

332-
return {newSearchResultKeys, handleSelectionListScroll, newTransactions};
314+
const hasQueuedHighlights = newSearchResultKeys !== null && newSearchResultKeys.size > 0;
315+
316+
return {newSearchResultKeys, handleSelectionListScroll, newTransactions, hasQueuedHighlights};
333317
}
334318

335319
/**

src/languages/de.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9260,7 +9260,7 @@ Hier ist ein *Testbeleg*, um dir zu zeigen, wie es funktioniert:`,
92609260
permissions: 'Gruppenberechtigungen',
92619261
createNewGroupButton: 'Neue Gruppe',
92629262
createGroupSubmitButton: 'Gruppe erstellen',
9263-
expensifyCardPreferredWorkspace: 'Expensify Card bevorzugter Arbeitsbereich',
9263+
expensifyCardPreferredWorkspace: 'Bevorzugter Workspace für Expensify Card',
92649264
expensifyCardPreferredWorkspaceDescription:
92659265
'Alle Expensify Card-Transaktionen werden im bevorzugten Expensify Card-Arbeitsbereich anstelle des bevorzugten Arbeitsbereichs erstellt. Durch Aktivieren dieser Funktion wird die Einstellung des bevorzugten Arbeitsbereichs nur für Expensify Card-Transaktionen überschrieben.',
92669266
strictlyEnforceWorkspaceRules: 'Workspace-Regeln strikt durchsetzen',
@@ -9281,7 +9281,7 @@ Hier ist ein *Testbeleg*, um dir zu zeigen, wie es funktioniert:`,
92819281
restrictDefaultLoginSelectionDescription:
92829282
'Verhindert, dass Mitglieder ihre Login-E-Mail-Adresse außerhalb der Unternehmensdomäne ändern, um Richtlinienbeschränkungen zu umgehen.',
92839283
expensifyCardPreferredWorkspaceDisabledMessage:
9284-
'Um diese Einstellung zu verwenden, muss der bevorzugte Workspace aktiviert und für die Domain die Expensify Card eingerichtet sein.',
9284+
'Um diese Einstellung zu aktivieren, aktiviere zuerst einen bevorzugten Workspace und richte Expensify Cards in deiner Domain ein.',
92859285
findGroup: 'Gruppe suchen',
92869286
},
92879287
},

src/languages/en.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9266,7 +9266,7 @@ const translations = {
92669266
permissions: 'Group permissions',
92679267
createNewGroupButton: 'New group',
92689268
createGroupSubmitButton: 'Create group',
9269-
expensifyCardPreferredWorkspace: 'Expensify Card Preferred Workspace',
9269+
expensifyCardPreferredWorkspace: 'Expensify Card preferred workspace',
92709270
expensifyCardPreferredWorkspaceDescription:
92719271
'All Expensify Card transactions will be created on the Expensify Card Preferred Workspace instead of the Preferred Workspace. Enabling this feature will override the Preferred Workspace setting for Expensify Card transactions only.',
92729272
strictlyEnforceWorkspaceRules: 'Strictly enforce workspace rules',
@@ -9285,7 +9285,7 @@ const translations = {
92859285
noWorkspacesMessage: 'There are no workspaces on this domain. A workspace is required to enable this restriction.',
92869286
restrictDefaultLoginSelection: 'Restrict default login selection',
92879287
restrictDefaultLoginSelectionDescription: 'Prevent members from changing their login email away from their company domain to avoid policy restrictions.',
9288-
expensifyCardPreferredWorkspaceDisabledMessage: 'To use this setting, Preferred Workspace must be enabled and the domain must have Expensify Card set up.',
9288+
expensifyCardPreferredWorkspaceDisabledMessage: 'To enable this setting, please first enable a preferred workspace and set up Expensify Cards on your domain.',
92899289
findGroup: 'Find group',
92909290
},
92919291
},

src/languages/es.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9480,7 +9480,7 @@ ${amount} para ${merchant} - ${date}`,
94809480
restrictDefaultLoginSelection: 'Restringir el inicio de sesión predeterminado',
94819481
restrictDefaultLoginSelectionDescription: 'Evita que los miembros cambien su correo de inicio de sesión fuera del dominio de la empresa para eludir restricciones de políticas.',
94829482
expensifyCardPreferredWorkspaceDisabledMessage:
9483-
'Para usar esta configuración, el espacio de trabajo preferido debe estar habilitado y el dominio debe tener Expensify Card configurada.',
9483+
'Para habilitar esta configuración, primero habilita un espacio de trabajo preferido y configura las Tarjetas Expensify en tu dominio.',
94849484
findGroup: 'Encontrar grupo',
94859485
},
94869486
},

src/languages/fr.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9283,7 +9283,7 @@ Voici un *reçu test* pour vous montrer comment ça fonctionne :`,
92839283
permissions: 'Autorisations du groupe',
92849284
createNewGroupButton: 'Nouveau groupe',
92859285
createGroupSubmitButton: 'Créer le groupe',
9286-
expensifyCardPreferredWorkspace: "Espace de travail préféré pour l'Expensify Card",
9286+
expensifyCardPreferredWorkspace: 'Espace de travail préféré pour la carte Expensify',
92879287
expensifyCardPreferredWorkspaceDescription:
92889288
"Toutes les transactions Expensify Card seront créées dans l'espace de travail préféré Expensify Card au lieu de l'espace de travail préféré.",
92899289
strictlyEnforceWorkspaceRules: 'Appliquer strictement les règles de l’espace de travail',
@@ -9305,8 +9305,9 @@ Voici un *reçu test* pour vous montrer comment ça fonctionne :`,
93059305
restrictDefaultLoginSelection: 'Restreindre la sélection de connexion par défaut',
93069306
restrictDefaultLoginSelectionDescription:
93079307
'Empêche les membres de modifier leur e-mail de connexion en dehors du domaine de leur entreprise afin d’éviter les restrictions de politique.',
9308+
93089309
expensifyCardPreferredWorkspaceDisabledMessage:
9309-
'Pour utiliser ce paramètre, l’espace de travail préféré doit être activé et la Expensify Card doit être configurée pour le domaine.',
9310+
'Pour activer ce paramètre, veuillez d’abord activer un espace de travail préféré et configurer les cartes Expensify sur votre domaine.',
93109311
findGroup: 'Trouver un groupe',
93119312
},
93129313
},

src/languages/it.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9252,7 +9252,7 @@ Ecco una *ricevuta di prova* per mostrarti come funziona:`,
92529252
permissions: 'Autorizzazioni del gruppo',
92539253
createNewGroupButton: 'Nuovo gruppo',
92549254
createGroupSubmitButton: 'Crea gruppo',
9255-
expensifyCardPreferredWorkspace: 'Area di lavoro preferita per Expensify Card',
9255+
expensifyCardPreferredWorkspace: 'Workspace preferito per Expensify Card',
92569256
expensifyCardPreferredWorkspaceDescription:
92579257
"Tutte le transazioni Expensify Card verranno create nell'area di lavoro preferita Expensify Card anziché nell'area di lavoro preferita.",
92589258
strictlyEnforceWorkspaceRules: 'Applica rigorosamente le regole dello spazio di lavoro',
@@ -9272,8 +9272,9 @@ Ecco una *ricevuta di prova* per mostrarti come funziona:`,
92729272
noWorkspacesMessage: 'Non ci sono spazi di lavoro su questo dominio. È necessario uno spazio di lavoro per abilitare questa restrizione.',
92739273
restrictDefaultLoginSelection: 'Limita la selezione di accesso predefinita',
92749274
restrictDefaultLoginSelectionDescription: 'Impedisce ai membri di modificare l’email di accesso al di fuori del dominio aziendale per eludere le restrizioni delle policy.',
9275+
92759276
expensifyCardPreferredWorkspaceDisabledMessage:
9276-
'Per utilizzare questa impostazione, l’area di lavoro preferita deve essere abilitata e la Expensify Card deve essere configurata per il dominio.',
9277+
'Per abilitare questa impostazione, abilita prima uno spazio di lavoro preferito e configura le Expensify Card per il tuo dominio.',
92779278
findGroup: 'Trova gruppo',
92789279
},
92799280
},

src/languages/ja.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9135,7 +9135,7 @@ ${reportName}
91359135
permissions: 'グループの権限',
91369136
createNewGroupButton: '新しいグループ',
91379137
createGroupSubmitButton: 'グループを作成',
9138-
expensifyCardPreferredWorkspace: 'Expensify Card 優先ワークスペース',
9138+
expensifyCardPreferredWorkspace: 'Expensify Card の優先ワークスペース',
91399139
expensifyCardPreferredWorkspaceDescription: 'すべてのExpensify Cardトランザクションは、優先ワークスペースではなくExpensify Card優先ワークスペースで作成されます。',
91409140
strictlyEnforceWorkspaceRules: 'ワークスペースのルールを厳密に適用する',
91419141
strictlyEnforceWorkspaceRulesDescription: 'レポートを送信する前にすべてのワークスペースのルールを満たす必要があります。手動による例外は許可されていません。',
@@ -9153,7 +9153,7 @@ ${reportName}
91539153
noWorkspacesMessage: 'このドメインにワークスペースがありません。この制限を有効にするにはワークスペースが必要です。',
91549154
restrictDefaultLoginSelection: 'デフォルトのログイン選択を制限する',
91559155
restrictDefaultLoginSelectionDescription: 'メンバーがポリシー制限を回避するために、ログイン用のメールアドレスを会社のドメイン以外に変更することを防ぎます。',
9156-
expensifyCardPreferredWorkspaceDisabledMessage: 'この設定を使用するには、優先ワークスペースを有効にし、ドメインに Expensify Card が設定されている必要があります。',
9156+
expensifyCardPreferredWorkspaceDisabledMessage: 'この設定を有効にするには、まず優先するワークスペースを有効にし、ドメインでExpensify Cardsを設定してください。',
91579157
findGroup: 'グループを検索',
91589158
},
91599159
},

src/languages/nl.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9240,8 +9240,7 @@ Hier is een *proefbon* om je te laten zien hoe het werkt:`,
92409240
noWorkspacesMessage: 'Er zijn geen werkruimtes op dit domein. Een werkruimte is vereist om deze beperking in te schakelen.',
92419241
restrictDefaultLoginSelection: 'Standaard login-selectie beperken',
92429242
restrictDefaultLoginSelectionDescription: 'Voorkomt dat leden hun login-e-mail wijzigen naar een adres buiten het bedrijfsdomein om beleidsbeperkingen te omzeilen.',
9243-
expensifyCardPreferredWorkspaceDisabledMessage:
9244-
'Om deze instelling te gebruiken, moet de voorkeurswerkruimte zijn ingeschakeld en moet voor het domein een Expensify Card zijn ingesteld.',
9243+
expensifyCardPreferredWorkspaceDisabledMessage: 'Om deze instelling in te schakelen, schakelt u eerst een voorkeurswerkruimte in en stelt u Expensify Cards in op uw domein.',
92459244
findGroup: 'Groep zoeken',
92469245
},
92479246
},

src/languages/pl.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9204,7 +9204,7 @@ Oto *paragon testowy*, żeby pokazać Ci, jak to działa:`,
92049204
permissions: 'Uprawnienia grupy',
92059205
createNewGroupButton: 'Nowa grupa',
92069206
createGroupSubmitButton: 'Utwórz grupę',
9207-
expensifyCardPreferredWorkspace: 'Preferowany obszar roboczy Expensify Card',
9207+
expensifyCardPreferredWorkspace: 'Preferowany workspace karty Expensify',
92089208
expensifyCardPreferredWorkspaceDescription:
92099209
'Wszystkie transakcje Expensify Card będą tworzone w preferowanym obszarze roboczym Expensify Card zamiast w preferowanym obszarze roboczym.',
92109210
strictlyEnforceWorkspaceRules: 'Ściśle egzekwuj reguły przestrzeni roboczej',
@@ -9223,8 +9223,7 @@ Oto *paragon testowy*, żeby pokazać Ci, jak to działa:`,
92239223
noWorkspacesMessage: 'W tej domenie nie ma żadnych obszarów roboczych. Obszar roboczy jest wymagany, aby włączyć to ograniczenie.',
92249224
restrictDefaultLoginSelection: 'Ogranicz wybór domyślnego logowania',
92259225
restrictDefaultLoginSelectionDescription: 'Zapobiega zmianie adresu e-mail do logowania przez członków na adres spoza domeny firmowej, aby obejść ograniczenia zasad.',
9226-
expensifyCardPreferredWorkspaceDisabledMessage:
9227-
'Aby korzystać z tego ustawienia, preferowana przestrzeń robocza musi być włączona, a domena musi mieć skonfigurowaną Expensify Card.',
9226+
expensifyCardPreferredWorkspaceDisabledMessage: 'Aby włączyć to ustawienie, najpierw włącz preferowane miejsce pracy i skonfiguruj karty Expensify w swojej domenie.',
92289227
findGroup: 'Znajdź grupę',
92299228
},
92309229
},

0 commit comments

Comments
 (0)