mirror of
https://github.com/jonasrafa/kunkun-ext-google-search.git
synced 2025-04-03 17:56:45 +00:00
Enhance Google Search extension with advanced features
- Add action panel with open, copy URL, and copy query actions - Improve error handling and toast notifications - Update package.json permissions for URL and clipboard access - Refactor result handling and decoding in handleResults.ts
This commit is contained in:
parent
1d81adbf47
commit
efdcea77b6
14
package.json
14
package.json
@ -10,7 +10,19 @@
|
||||
"longDescription": "Google search with autosuggestions",
|
||||
"identifier": "google-search",
|
||||
"permissions": [
|
||||
"fetch:all"
|
||||
"fetch:all",
|
||||
"clipboard:write-text",
|
||||
{
|
||||
"permission": "open:url",
|
||||
"allow": [
|
||||
{
|
||||
"url": "https://**"
|
||||
},
|
||||
{
|
||||
"url": "http://**"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"demoImages": [],
|
||||
"icon": {
|
||||
|
106
src/index.ts
106
src/index.ts
@ -1,7 +1,24 @@
|
||||
import { expose, List, TemplateUiCommand, ui } from "@kksh/api/ui/template";
|
||||
import {
|
||||
Action,
|
||||
clipboard,
|
||||
expose,
|
||||
Icon,
|
||||
IconEnum,
|
||||
List,
|
||||
open,
|
||||
TemplateUiCommand,
|
||||
toast,
|
||||
ui,
|
||||
} from "@kksh/api/ui/template";
|
||||
import { getAutoSearchResults, getStaticResult } from "./utils/handleResults";
|
||||
import { SearchResult } from "./utils/types";
|
||||
|
||||
const Actions = {
|
||||
OpenInBrowser: "Open in Browser",
|
||||
CopyUrl: "Copy URL",
|
||||
CopyQuery: "Copy Query",
|
||||
};
|
||||
|
||||
class DemoExtension extends TemplateUiCommand {
|
||||
private isLoading: boolean = false;
|
||||
private results: SearchResult[] = [];
|
||||
@ -54,11 +71,7 @@ class DemoExtension extends TemplateUiCommand {
|
||||
}
|
||||
|
||||
console.error("Search error", error);
|
||||
ui.showToast({
|
||||
style: "error",
|
||||
title: "Could not perform search",
|
||||
message: String(error),
|
||||
});
|
||||
toast.error(`Could not perform search ${String(error)}`);
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,11 +92,45 @@ class DemoExtension extends TemplateUiCommand {
|
||||
new List.List({
|
||||
sections: [
|
||||
new List.Section({
|
||||
title: "Results",
|
||||
items: this.results.map(
|
||||
(result) =>
|
||||
new List.Item({
|
||||
title: result.query,
|
||||
value: result.id,
|
||||
value: result.url,
|
||||
defaultAction: Actions.OpenInBrowser,
|
||||
actions: new Action.ActionPanel({
|
||||
items: [
|
||||
new Action.Action({
|
||||
title: Actions.OpenInBrowser,
|
||||
value: Actions.OpenInBrowser,
|
||||
icon: new Icon({
|
||||
type: IconEnum.Iconify,
|
||||
value: "material-symbols:open-in-new",
|
||||
}),
|
||||
}),
|
||||
new Action.Action({
|
||||
title: Actions.CopyUrl,
|
||||
value: Actions.CopyUrl,
|
||||
icon: new Icon({
|
||||
type: IconEnum.Iconify,
|
||||
value: "material-symbols:copy-all-outline",
|
||||
}),
|
||||
}),
|
||||
new Action.Action({
|
||||
title: Actions.CopyQuery,
|
||||
value: Actions.CopyQuery,
|
||||
icon: new Icon({
|
||||
type: IconEnum.Iconify,
|
||||
value: "material-symbols:copy-all-outline",
|
||||
}),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
icon: new Icon({
|
||||
type: IconEnum.Iconify,
|
||||
value: "material-symbols:search",
|
||||
}),
|
||||
})
|
||||
),
|
||||
}),
|
||||
@ -92,6 +139,51 @@ class DemoExtension extends TemplateUiCommand {
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
onListItemSelected(value: string): Promise<void> {
|
||||
return open.url(value);
|
||||
}
|
||||
|
||||
onActionSelected(value: string): Promise<void> {
|
||||
if (this.highlightedListItemValue) {
|
||||
if (value === Actions.OpenInBrowser) {
|
||||
console.log(this.highlightedListItemValue);
|
||||
return open.url(this.highlightedListItemValue);
|
||||
}
|
||||
|
||||
if (value === Actions.CopyUrl) {
|
||||
return clipboard
|
||||
.writeText(this.highlightedListItemValue)
|
||||
.then(() => {
|
||||
return toast.success("Copied URL to clipboard");
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
return toast.error("Failed to copy URL to clipboard");
|
||||
});
|
||||
}
|
||||
|
||||
if (value === Actions.CopyQuery) {
|
||||
const query = this.results.find(
|
||||
(result) => result.url === this.highlightedListItemValue
|
||||
)?.query;
|
||||
if (query) {
|
||||
return clipboard
|
||||
.writeText(query)
|
||||
.then(() => {
|
||||
return toast.success("Copied query to clipboard");
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
return toast.error("Failed to copy query to clipboard");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
}
|
||||
return toast.warning("No item selected").then(() => {});
|
||||
}
|
||||
}
|
||||
|
||||
expose(new DemoExtension());
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { nanoid } from "nanoid";
|
||||
import { Preferences, SearchResult } from "./types";
|
||||
import iconv from "iconv-lite";
|
||||
import type { Preferences, SearchResult } from "./types";
|
||||
import { fetch } from "@kksh/api/ui/template";
|
||||
|
||||
// export async function getSearchHistory(): Promise<SearchResult[]> {
|
||||
@ -41,52 +40,59 @@ export async function getAutoSearchResults(
|
||||
searchText: string,
|
||||
signal: any
|
||||
): Promise<SearchResult[]> {
|
||||
const response = await fetch(
|
||||
`https://suggestqueries.google.com/complete/search?hl=en-us&output=chrome&q=${encodeURIComponent(
|
||||
searchText
|
||||
)}`,
|
||||
{
|
||||
method: "get",
|
||||
signal: signal,
|
||||
headers: {
|
||||
"Content-Type": "text/plain; charset=UTF-8",
|
||||
},
|
||||
}
|
||||
);
|
||||
try {
|
||||
const response = await fetch(
|
||||
`https://suggestqueries.google.com/complete/search?hl=en-us&output=chrome&q=${encodeURIComponent(
|
||||
searchText
|
||||
)}`,
|
||||
{
|
||||
method: "get",
|
||||
signal: signal,
|
||||
headers: {
|
||||
"Content-Type": "text/plain; charset=UTF-8",
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
return Promise.reject(response.statusText);
|
||||
if (!response.ok) {
|
||||
console.error("Response not OK", response.status, response.statusText);
|
||||
return Promise.reject(response.statusText);
|
||||
}
|
||||
|
||||
const buffer = await response.arrayBuffer();
|
||||
const decoder = new TextDecoder("iso-8859-1");
|
||||
const text = decoder.decode(buffer);
|
||||
const json = JSON.parse(text);
|
||||
|
||||
const results: SearchResult[] = [];
|
||||
|
||||
json[1].map((item: string, i: number) => {
|
||||
const type = json[4]["google:suggesttype"][i];
|
||||
const description = json[2][i];
|
||||
|
||||
if (type === "NAVIGATION") {
|
||||
results.push({
|
||||
id: nanoid(),
|
||||
query: description.length > 0 ? description : item,
|
||||
description: `Open URL for '${item}'`,
|
||||
url: item,
|
||||
isNavigation: true,
|
||||
});
|
||||
} else if (type === "QUERY") {
|
||||
results.push({
|
||||
id: nanoid(),
|
||||
query: item,
|
||||
description: `Search Google for '${item}'`,
|
||||
url: `https://www.google.com/search?q=${encodeURIComponent(item)}`,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
console.log(results);
|
||||
|
||||
return results;
|
||||
} catch (error) {
|
||||
console.error("Error in getAutoSearchResults", error);
|
||||
return Promise.reject(error);
|
||||
}
|
||||
|
||||
const buffer = await response.arrayBuffer();
|
||||
const text = iconv.decode(Buffer.from(buffer), "iso-8859-1");
|
||||
const json = JSON.parse(text);
|
||||
|
||||
const results: SearchResult[] = [];
|
||||
|
||||
json[1].map((item: string, i: number) => {
|
||||
const type = json[4]["google:suggesttype"][i];
|
||||
const description = json[2][i];
|
||||
|
||||
if (type === "NAVIGATION") {
|
||||
results.push({
|
||||
id: nanoid(),
|
||||
query: description.length > 0 ? description : item,
|
||||
description: `Open URL for '${item}'`,
|
||||
url: item,
|
||||
isNavigation: true,
|
||||
});
|
||||
} else if (type === "QUERY") {
|
||||
results.push({
|
||||
id: nanoid(),
|
||||
query: item,
|
||||
description: `Search Google for '${item}'`,
|
||||
url: `https://www.google.com/search?q=${encodeURIComponent(item)}`,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
console.log(results);
|
||||
|
||||
return results;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user