Skip to content

Commit 71d3076

Browse files
committed
Improvement: Add base definition for recently used sections.
1 parent 725991b commit 71d3076

11 files changed

Lines changed: 250 additions & 65 deletions

gnome-extensions/extension/features/RecentlyUsed/definitions/recentlyUsedDefinitionClipboard.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { GlobalActionService } from '../../../shared/services/serviceAction.js';
22
import { searchViaProvider } from '../../../shared/services/serviceSearchHub.js';
33

44
import { RecentlyUsedDefaultPolicy } from '../constants/recentlyUsedPolicyConstants.js';
5+
import { RecentlyUsedSectionDefinition } from '../registry/recentlyUsedSectionDefinition.js';
56
import { renderRecentlyUsedClipboardListContent } from '../integrations/recentlyUsedIntegrationClipboard.js';
67

78
import { ClipboardProvider } from '../../Clipboard/constants/clipboardConstants.js';
@@ -14,7 +15,7 @@ import { ensureClipboardSearchProviderRegistered } from '../../Clipboard/integra
1415
* @returns {object} Clipboard section definition instance.
1516
*/
1617
function createRecentlyUsedDefinitionClipboardInstance() {
17-
const definition = {
18+
const definition = new RecentlyUsedSectionDefinition({
1819
id: 'clipboard',
1920
targetTab: 'Clipboard',
2021
layoutType: 'list',
@@ -37,7 +38,7 @@ function createRecentlyUsedDefinitionClipboardInstance() {
3738
},
3839
},
3940
gridPresentation: null,
40-
};
41+
});
4142

4243
/**
4344
* Initializes the clipboard section.

gnome-extensions/extension/features/RecentlyUsed/definitions/recentlyUsedDefinitionEmoji.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { GlobalActionService } from '../../../shared/services/serviceAction.js';
22
import { searchViaProvider } from '../../../shared/services/serviceSearchHub.js';
33

44
import { RecentlyUsedDefaultPolicy } from '../constants/recentlyUsedPolicyConstants.js';
5+
import { RecentlyUsedSectionDefinition } from '../registry/recentlyUsedSectionDefinition.js';
56
import { setRecentlyUsedClipboardText } from '../integrations/recentlyUsedIntegrationClipboard.js';
67
import { createRecentlyUsedRecentsManager, resolveRecentlyUsedRecentFilePath } from '../integrations/recentlyUsedIntegrationRecents.js';
78

@@ -18,7 +19,7 @@ function createRecentlyUsedDefinitionEmojiInstance() {
1819
let recentManager = null;
1920
let emojiSearchRenderer = null;
2021

21-
const definition = {
22+
const definition = new RecentlyUsedSectionDefinition({
2223
id: 'emoji',
2324
targetTab: 'Emoji',
2425
layoutType: 'grid',
@@ -35,7 +36,7 @@ function createRecentlyUsedDefinitionEmojiInstance() {
3536
icon: null,
3637
},
3738
listPresentation: null,
38-
};
39+
});
3940

4041
/**
4142
* Initializes the emoji recents manager.

gnome-extensions/extension/features/RecentlyUsed/definitions/recentlyUsedDefinitionGif.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { searchViaProvider } from '../../../shared/services/serviceSearchHub.js'
77

88
import { matchesRecentlyUsedSearch } from '../utilities/recentlyUsedSearch.js';
99
import { RecentlyUsedDefaultPolicy } from '../constants/recentlyUsedPolicyConstants.js';
10+
import { RecentlyUsedSectionDefinition } from '../registry/recentlyUsedSectionDefinition.js';
1011
import { createRecentlyUsedRecentsManager, resolveRecentlyUsedRecentFilePath } from '../integrations/recentlyUsedIntegrationRecents.js';
1112
import { getRecentlyUsedGifRuntime, destroyRecentlyUsedGifRuntime, copyRecentlyUsedGifToClipboard } from '../integrations/recentlyUsedIntegrationGif.js';
1213

@@ -26,7 +27,7 @@ const GIF_PLACEHOLDER = {
2627
function createRecentlyUsedDefinitionGifInstance() {
2728
let recentManager = null;
2829

29-
const definition = {
30+
const definition = new RecentlyUsedSectionDefinition({
3031
id: 'gif',
3132
targetTab: 'GIF',
3233
layoutType: 'grid',
@@ -45,7 +46,7 @@ function createRecentlyUsedDefinitionGifInstance() {
4546
},
4647
},
4748
listPresentation: null,
48-
};
49+
});
4950

5051
/**
5152
* Initializes GIF recents and runtime services.

gnome-extensions/extension/features/RecentlyUsed/definitions/recentlyUsedDefinitionKaomoji.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { GlobalActionService } from '../../../shared/services/serviceAction.js';
22
import { searchViaProvider } from '../../../shared/services/serviceSearchHub.js';
33

44
import { RecentlyUsedDefaultPolicy } from '../constants/recentlyUsedPolicyConstants.js';
5+
import { RecentlyUsedSectionDefinition } from '../registry/recentlyUsedSectionDefinition.js';
56
import { setRecentlyUsedClipboardText } from '../integrations/recentlyUsedIntegrationClipboard.js';
67
import { createRecentlyUsedRecentsManager, resolveRecentlyUsedRecentFilePath } from '../integrations/recentlyUsedIntegrationRecents.js';
78

@@ -18,7 +19,7 @@ function createRecentlyUsedDefinitionKaomojiInstance() {
1819
let recentManager = null;
1920
let kaomojiSearchRenderer = null;
2021

21-
const definition = {
22+
const definition = new RecentlyUsedSectionDefinition({
2223
id: 'kaomoji',
2324
targetTab: 'Kaomoji',
2425
layoutType: 'list',
@@ -41,7 +42,7 @@ function createRecentlyUsedDefinitionKaomojiInstance() {
4142
},
4243
},
4344
gridPresentation: null,
44-
};
45+
});
4546

4647
/**
4748
* Initializes the kaomoji recents manager.

gnome-extensions/extension/features/RecentlyUsed/definitions/recentlyUsedDefinitionPinned.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { GlobalActionService } from '../../../shared/services/serviceAction.js';
22
import { searchViaProvider } from '../../../shared/services/serviceSearchHub.js';
33

4+
import { RecentlyUsedSectionDefinition } from '../registry/recentlyUsedSectionDefinition.js';
45
import { RecentlyUsedUI } from '../constants/recentlyUsedConstants.js';
56
import { renderRecentlyUsedClipboardListContent } from '../integrations/recentlyUsedIntegrationClipboard.js';
67
import { RecentlyUsedDefaultPolicy, RecentlyUsedLimitMode } from '../constants/recentlyUsedPolicyConstants.js';
@@ -15,7 +16,7 @@ import { ensureClipboardSearchProviderRegistered } from '../../Clipboard/integra
1516
* @returns {object} Pinned section definition instance.
1617
*/
1718
function createRecentlyUsedDefinitionPinnedInstance() {
18-
const definition = {
19+
const definition = new RecentlyUsedSectionDefinition({
1920
id: 'pinned',
2021
targetTab: 'Clipboard',
2122
layoutType: 'list',
@@ -51,7 +52,7 @@ function createRecentlyUsedDefinitionPinnedInstance() {
5152
},
5253
},
5354
gridPresentation: null,
54-
};
55+
});
5556

5657
/**
5758
* Initializes the pinned section.

gnome-extensions/extension/features/RecentlyUsed/definitions/recentlyUsedDefinitionSymbols.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { GlobalActionService } from '../../../shared/services/serviceAction.js';
22
import { searchViaProvider } from '../../../shared/services/serviceSearchHub.js';
33

44
import { RecentlyUsedDefaultPolicy } from '../constants/recentlyUsedPolicyConstants.js';
5+
import { RecentlyUsedSectionDefinition } from '../registry/recentlyUsedSectionDefinition.js';
56
import { setRecentlyUsedClipboardText } from '../integrations/recentlyUsedIntegrationClipboard.js';
67
import { createRecentlyUsedRecentsManager, resolveRecentlyUsedRecentFilePath } from '../integrations/recentlyUsedIntegrationRecents.js';
78

@@ -18,7 +19,7 @@ function createRecentlyUsedDefinitionSymbolsInstance() {
1819
let recentManager = null;
1920
let symbolsSearchRenderer = null;
2021

21-
const definition = {
22+
const definition = new RecentlyUsedSectionDefinition({
2223
id: 'symbols',
2324
targetTab: 'Symbols',
2425
layoutType: 'grid',
@@ -35,7 +36,7 @@ function createRecentlyUsedDefinitionSymbolsInstance() {
3536
icon: null,
3637
},
3738
listPresentation: null,
38-
};
39+
});
3940

4041
/**
4142
* Initializes the symbols recents manager.

gnome-extensions/extension/features/RecentlyUsed/registry/recentlyUsedRegistry.js

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { gettext as _ } from 'resource:///org/gnome/shell/extensions/extension.j
22

33
import { Logger } from '../../../shared/utilities/utilityLogger.js';
44

5+
import { ensureRecentlyUsedSectionDefinition } from './recentlyUsedSectionDefinition.js';
56
import { getRecentlyUsedOrder } from '../definitions/recentlyUsedOrder.js';
67

78
let recentlyUsedRegistry = null;
@@ -100,11 +101,17 @@ export async function initializeRecentlyUsedRegistry() {
100101
return null;
101102
}
102103

103-
return {
104-
...sectionDefinition,
105-
...orderEntry,
106-
id: sectionDefinition.id,
107-
};
104+
const normalizedSectionDefinition = ensureRecentlyUsedSectionDefinition(sectionDefinition);
105+
if (!normalizedSectionDefinition) {
106+
return null;
107+
}
108+
109+
const sectionDefinitionId = normalizedSectionDefinition.id;
110+
Object.assign(normalizedSectionDefinition, orderEntry, {
111+
id: sectionDefinitionId,
112+
});
113+
114+
return normalizedSectionDefinition;
108115
}),
109116
);
110117
registerRecentlyUsedSections(sectionDefinitions.filter(Boolean));

gnome-extensions/extension/features/RecentlyUsed/registry/recentlyUsedRuntimeService.js

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { isCallable } from '../../../shared/utilities/utilityFunction.js';
22
import { Logger } from '../../../shared/utilities/utilityLogger.js';
33

4+
import { ensureRecentlyUsedSectionDefinition } from './recentlyUsedSectionDefinition.js';
45
import { normalizeRecentlyUsedSearchQuery } from '../utilities/recentlyUsedSearch.js';
56
import { RecentlyUsedDisplayMode } from '../constants/recentlyUsedPolicyConstants.js';
67
import { RecentlyUsedSearchStateManager } from './recentlyUsedSearchStateManager.js';
@@ -77,10 +78,6 @@ export class RecentlyUsedRuntimeService {
7778
stop() {
7879
const sectionDefinitions = this.getOrderedSections();
7980
for (const section of sectionDefinitions) {
80-
if (!isCallable(section.destroy)) {
81-
continue;
82-
}
83-
8481
try {
8582
section.destroy();
8683
} catch {
@@ -133,16 +130,23 @@ export class RecentlyUsedRuntimeService {
133130
return sectionDefinition;
134131
}
135132

136-
const instanceId = typeof instance.id === 'string' && instance.id.length > 0 ? instance.id : sectionDefinition.id;
133+
const normalizedInstance = ensureRecentlyUsedSectionDefinition(instance);
134+
if (!normalizedInstance) {
135+
return sectionDefinition;
136+
}
137+
138+
const instanceId = typeof normalizedInstance.id === 'string' && normalizedInstance.id.length > 0 ? normalizedInstance.id : sectionDefinition.id;
137139
if (instanceId !== sectionDefinition.id) {
138140
Logger.warn(`Recently Used section '${sectionDefinition.id || '<unknown>'}' createInstance() returned mismatched id '${instanceId}'. Using template id.`);
139141
}
140142

141-
return {
142-
...sectionDefinition,
143-
...instance,
143+
const sectionDefinitionData = { ...sectionDefinition };
144+
const instanceData = { ...normalizedInstance };
145+
Object.assign(normalizedInstance, sectionDefinitionData, instanceData, {
144146
id: sectionDefinition.id,
145-
};
147+
});
148+
149+
return normalizedInstance;
146150
} catch (e) {
147151
const message = e?.message ?? String(e);
148152
Logger.warn(`Failed to instantiate Recently Used section '${sectionDefinition.id || '<unknown>'}': ${message}`);
@@ -171,10 +175,6 @@ export class RecentlyUsedRuntimeService {
171175

172176
await Promise.all(
173177
sectionDefinitions.map(async (section) => {
174-
if (!isCallable(section.initialize)) {
175-
return;
176-
}
177-
178178
try {
179179
await section.initialize({
180180
extensionUuid: this._extension.uuid,
@@ -256,7 +256,7 @@ export class RecentlyUsedRuntimeService {
256256
searchQuery,
257257
};
258258

259-
if (isCallable(sectionConfig.isEnabled) && !sectionConfig.isEnabled(runtimeContext)) {
259+
if (!sectionConfig.isEnabled(runtimeContext)) {
260260
return invisibleModel;
261261
}
262262

@@ -265,8 +265,7 @@ export class RecentlyUsedRuntimeService {
265265
return invisibleModel;
266266
}
267267

268-
const mapItem = isCallable(sectionConfig.mapItem) ? sectionConfig.mapItem : (item) => item;
269-
const mappedItems = sourceItems.map((item) => mapItem(item));
268+
const mappedItems = sourceItems.map((item) => sectionConfig.mapItem(item));
270269
const filteredItems = searchQuery.length > 0 ? mappedItems.filter((item) => this._searchStateManager.matchesSectionSearch(sectionConfig, item, searchQuery, runtimeContext)) : mappedItems;
271270

272271
if (filteredItems.length === 0) {
@@ -291,7 +290,7 @@ export class RecentlyUsedRuntimeService {
291290
async handleItemClick(itemData, sectionId) {
292291
const sectionDefinition = this._getSectionById(sectionId);
293292

294-
if (!isCallable(sectionDefinition?.onClick)) {
293+
if (!sectionDefinition) {
295294
return false;
296295
}
297296

@@ -353,18 +352,16 @@ export class RecentlyUsedRuntimeService {
353352
gridLayout,
354353
listLayout,
355354
nestedLayout,
356-
listContentRenderer: isCallable(sectionConfig.renderListContent) ? (args) => sectionConfig.renderListContent(args) : null,
357-
gridIconResolver: isCallable(sectionConfig.resolveGridIcon) ? (iconKind) => sectionConfig.resolveGridIcon(iconKind) : null,
358-
onGridItemCreated: isCallable(sectionConfig.onGridItemCreated)
359-
? ({ item, widget }) =>
360-
sectionConfig.onGridItemCreated({
361-
item,
362-
widget,
363-
renderSession: viewRuntimeContext.renderSession,
364-
currentRenderSession: viewRuntimeContext.currentRenderSession,
365-
widgetFactory: viewRuntimeContext.widgetFactory,
366-
})
367-
: null,
355+
listContentRenderer: (args) => sectionConfig.renderListContent(args),
356+
gridIconResolver: (iconKind) => sectionConfig.resolveGridIcon(iconKind),
357+
onGridItemCreated: ({ item, widget }) =>
358+
sectionConfig.onGridItemCreated({
359+
item,
360+
widget,
361+
renderSession: viewRuntimeContext.renderSession,
362+
currentRenderSession: viewRuntimeContext.currentRenderSession,
363+
widgetFactory: viewRuntimeContext.widgetFactory,
364+
}),
368365
};
369366
}
370367

gnome-extensions/extension/features/RecentlyUsed/registry/recentlyUsedSearchStateManager.js

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,11 @@ export class RecentlyUsedSearchStateManager {
4141
* @returns {Array<object>} Source items for current render pass.
4242
*/
4343
resolveSectionSourceItems(sectionConfig, runtimeContext, searchQuery) {
44-
const localItemsRaw = isCallable(sectionConfig.getItems) ? sectionConfig.getItems(runtimeContext) : [];
44+
const localItemsRaw = sectionConfig.getItems(runtimeContext);
4545
const localItems = Array.isArray(localItemsRaw) ? localItemsRaw : [];
4646
const localItemsSignature = this._createSectionItemsSignature(localItems);
4747

48-
if (!searchQuery || !isCallable(sectionConfig.searchItems) || !sectionConfig.id) {
48+
if (!searchQuery || !sectionConfig.id) {
4949
if (sectionConfig?.id) {
5050
this._sectionSearchState.delete(sectionConfig.id);
5151
}
@@ -118,19 +118,17 @@ export class RecentlyUsedSearchStateManager {
118118
* @returns {boolean} True when the item matches.
119119
*/
120120
matchesSectionSearch(sectionConfig, item, query, runtimeContext) {
121-
if (isCallable(sectionConfig?.matchesSearch)) {
122-
try {
123-
return Boolean(
124-
sectionConfig.matchesSearch({
125-
item,
126-
query,
127-
runtimeContext,
128-
fallbackMatch: (candidate) => matchesRecentlyUsedSearch({ item: candidate, query }),
129-
}),
130-
);
131-
} catch {
132-
// Fall back to generic matching when a custom matcher fails.
133-
}
121+
try {
122+
return Boolean(
123+
sectionConfig.matchesSearch({
124+
item,
125+
query,
126+
runtimeContext,
127+
fallbackMatch: (candidate) => matchesRecentlyUsedSearch({ item: candidate, query }),
128+
}),
129+
);
130+
} catch {
131+
// Fall back to generic matching when a custom matcher fails.
134132
}
135133

136134
return matchesRecentlyUsedSearch({ item, query });

0 commit comments

Comments
 (0)