PluginProbe
Extendify / 3.2.1
Extendify v3.2.1
3.2.1 3.2.0 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.6 3.0.5 3.0.4 trunk 0.1.0 0.10.0 0.10.1 0.10.2 0.11.0 0.11.1 0.2.0 0.3.0 0.3.1 0.4.0 0.5.0 0.6.0 All 127 releases
extendify / src / Recommendations / state / plugin-search.js

plugin-search.js in Extendify 3.2.1, at src/Recommendations/state/plugin-search.js

140 lines 3.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { extractPluginSlugs } from '@recommendations/utils/extract-plugin-slugs';
2 import { getAllPlugins } from '@shared/api/wp';
3 import { create } from 'zustand';
4 import { devtools } from 'zustand/middleware';
5
6 /* global jQuery */
7
8 const state = (set, get) => ({
9 query: null,
10 searchPlugins: [],
11 installedPlugins: [],
12 searchPluginsLimit: 6,
13 recommendationsLimit: 2,
14 isSearchPluginsLoading: false,
15 isSearchPluginsError: false,
16 isInstalledPluginsLoading: false,
17 isInstalledPluginsError: false,
18 initialize: () => {
19 get().startListeningToAjax();
20 get().fetchInstalledPlugins();
21 },
22 startListeningToAjax: () => {
23 // Initial query is present if the page loaded is already a search.
24 const initialQuery = new URLSearchParams(window.location.search).get('s');
25
26 if (initialQuery) {
27 const searchResults = document.getElementById('plugin-filter');
28 const pluginSlugs = extractPluginSlugs(searchResults);
29
30 set({
31 query: initialQuery,
32 searchPlugins: pluginSlugs,
33 });
34 }
35
36 const parser = new DOMParser();
37
38 window.jQuery?.ajaxSetup({
39 beforeSend: (_, settings) => {
40 const params = new URLSearchParams(settings.data);
41 const action = params.get('action');
42 const search = params.get('s');
43
44 if (action !== 'search-install-plugins') {
45 return;
46 }
47
48 settings.success = (xhr) => {
49 const doingRedirect =
50 typeof xhr === 'string' && xhr?.startsWith('<!DOCTYPE html>');
51 if (doingRedirect) {
52 // plugin is attempting to redirect - trigger a search
53 const i = window.jQuery('#search-plugins');
54 const value = i.val();
55 // either remove trailing space or add one
56 i.val(value.endsWith(' ') ? value.trim() : `${value} `);
57 i.trigger('keyup');
58 return;
59 }
60
61 try {
62 const parsedData = parser.parseFromString(
63 xhr?.data?.items || '',
64 'text/html',
65 );
66 const pluginSlugs = extractPluginSlugs(parsedData);
67
68 set({
69 searchPlugins: pluginSlugs,
70 isSearchPluginsLoading: false,
71 isSearchPluginsError: false,
72 });
73 } catch (_error) {
74 set({
75 searchPlugins: [],
76 isSearchPluginsLoading: false,
77 isSearchPluginsError: true,
78 });
79 }
80 };
81
82 settings.error = () => {
83 set({
84 searchPlugins: [],
85 isSearchPluginsLoading: false,
86 isSearchPluginsError: true,
87 });
88 };
89
90 set({
91 query: search ? search : null,
92 searchPlugins: [],
93 isSearchPluginsLoading: !!search,
94 isSearchPluginsError: false,
95 });
96 },
97 });
98 },
99 fetchInstalledPlugins: async (force = false) => {
100 if (get().installedPlugins.length && !force) {
101 return;
102 }
103
104 try {
105 set({
106 isInstalledPluginsLoading: true,
107 isInstalledPluginsError: false,
108 });
109
110 // Fetch installed plugins.
111 const data = await getAllPlugins();
112
113 set({
114 installedPlugins: data?.map((plugin) => ({
115 // We are extracting only the slug because the `plugin` value
116 // looks like `plugin-slug/plugin-file-name`.
117 slug: plugin.plugin.split('/')[0],
118 status: plugin.status,
119 })),
120 isInstalledPluginsLoading: false,
121 isInstalledPluginsError: false,
122 });
123 } catch (_) {
124 set({
125 installedPlugins: [],
126 isInstalledPluginsLoading: false,
127 isInstalledPluginsError: true,
128 });
129 }
130 },
131 });
132
133 const createInitializedStore = () => {
134 const store = create(devtools(state, { name: 'Extendify Plugin Search' }));
135 store.getState().initialize();
136 return store;
137 };
138
139 export const usePluginSearchStore = createInitializedStore();
140