-
Notifications
You must be signed in to change notification settings - Fork 2.7k
/
TranslationsList.tsx
106 lines (91 loc) · 3.51 KB
/
TranslationsList.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import { useEffect, useState, useCallback } from "react";
import { Action, ActionPanel, Icon, List, showToast, Clipboard } from "@raycast/api";
import translate, { Languages, Translations } from "dictcc";
import { createInputFromSearchTerm, getListSubtitle, joinStringsWithDelimiter, playAudio } from "../utils";
import { ListWithEmptyView } from "./ListWithEmptyView";
interface ITranslationsListProps {
isSearchFromClipboard?: boolean;
}
export function TranslationsList({ isSearchFromClipboard }: ITranslationsListProps) {
const [translations, setTranslations] = useState<Translations[] | undefined>();
const [url, setUrl] = useState<string | undefined>();
const [languages, setLanguages] = useState<[/* source */ Languages, /* target */ Languages] | undefined>();
const [loading, setLoading] = useState(false);
const [searchText, setSearchText] = useState("");
const fetchTranslations = useCallback(
async (searchTerm: string) => {
setSearchText(searchTerm);
setLoading(true);
try {
const input = createInputFromSearchTerm(searchTerm);
const { data, error, url } = await translate(input);
if (error) {
throw error;
}
setTranslations(data);
setUrl(url);
setLanguages([input.sourceLanguage, input.targetLanguage]);
} catch (error) {
if (error instanceof Error) {
showToast({
title: "Error",
message: error.message,
});
}
}
setLoading(false);
},
[setTranslations, setUrl, setLanguages, setLoading]
);
useEffect(() => {
if (isSearchFromClipboard) {
(async () => {
const clipboardText = await Clipboard.readText();
if (clipboardText && clipboardText !== searchText) {
fetchTranslations(clipboardText);
}
})();
}
}, [isSearchFromClipboard, fetchTranslations, searchText]);
return (
<List
isLoading={loading}
searchText={searchText}
onSearchTextChange={(text) => fetchTranslations(text)}
navigationTitle="Search dict.cc"
searchBarPlaceholder="Search term (e.g. 'en de Home', or 'Home')"
throttle
>
<ListWithEmptyView loading={loading} showNoResultsFound={!!searchText.length} />
<List.Section title="Results" subtitle={getListSubtitle(loading, languages, translations?.length)}>
{translations?.map((translation, index) => (
<List.Item
key={index}
title={translation.targetTranslation.text}
subtitle={translation.sourceTranslation.text}
accessories={[
{ text: joinStringsWithDelimiter(translation.targetTranslation.meta.abbreviations) },
{ text: joinStringsWithDelimiter(translation.targetTranslation.meta.comments) },
{ text: joinStringsWithDelimiter(translation.targetTranslation.meta.wordClassDefinitions) },
]}
actions={
<ActionPanel>
<Action.CopyToClipboard
title="Copy Text"
content={translation.targetTranslation.text}
shortcut={{ modifiers: ["cmd"], key: "." }}
/>
<Action
title="Play audio"
icon={Icon.Play}
onAction={() => playAudio(translation.targetTranslationAudioUrl)}
/>
{url && <Action.OpenInBrowser url={url} />}
</ActionPanel>
}
/>
))}
</List.Section>
</List>
);
}