Skip to content

Commit

Permalink
feat: Add source views to /translate and /recognise to see exactl…
Browse files Browse the repository at this point in the history
…y where the translations and detections came from. (#352)

Closes #344.
  • Loading branch information
vxern authored Jun 23, 2024
2 parents e3e8183 + 2715e7f commit 10c397f
Show file tree
Hide file tree
Showing 23 changed files with 890 additions and 767 deletions.
1,444 changes: 723 additions & 721 deletions assets/localisations/commands/eng-US.json

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions source/constants/contexts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -865,6 +865,12 @@ export default Object.freeze({
translation: localise("game.strings.translation", locale)(),
sourcedFrom: localise("game.strings.sourcedFrom", locale),
}),
translationsSourcedFrom: ({ localise, locale }) => ({
sourcedFrom: localise("translate.strings.sourcedFrom", locale),
}),
recognitionsMadeBy: ({ localise, locale }) => ({
recognitionsMadeBy: localise("recognise.strings.recognitionsMadeBy", locale)(),
}),
pardoned: ({ localise, locale }) => ({
title: localise("pardon.strings.pardoned.title", locale)(),
description: localise("pardon.strings.pardoned.description", locale),
Expand Down
42 changes: 37 additions & 5 deletions source/constants/licences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import apache from "logos:constants/licences/apache";
import bsd from "logos:constants/licences/bsd";
import mit from "logos:constants/licences/mit";

interface DictionaryLicence {
interface Licence {
readonly name: string;
readonly link: string;
readonly faviconLink?: string;
readonly notices: {
readonly notices?: {
readonly licence: string;
readonly copyright?: string;
readonly badgeLink?: string;
Expand Down Expand Up @@ -72,7 +72,39 @@ You must also include, in your app or site, wherever you provide attributions or
"You may cache and thus store API Data on your system for up to 24 hours, after which such cached API Data must be purged. Subject to that exception, you will not copy, store, archive, distribute to any third party (other than to End Users as contemplated in this Agreement) any API Data, any metadata or any Link. You agree that any cached API Data will be used by you only for the purpose of populating the Developer Application.",
},
},
} satisfies Record<string, DictionaryLicence>,
} satisfies Record<string, Licence>,
translators: {
deepl: {
name: "DeepL",
link: "https://www.deepl.com/translator/",
},
googleTranslate: {
name: "Google Translate",
link: "https://translate.google.com/",
},
lingvanex: {
name: "Lingvanex",
link: "https://lingvanex.com/translate/",
},
} satisfies Record<string, Licence>,
detectors: {
cld: {
name: "CLD",
link: "https://npmjs.com/package/cldpre",
},
eld: {
name: "ELD",
link: "https://github.com/vxern/efficient-language-detector-js",
},
fasttext: {
name: "fastText",
link: "https://npmjs.com/package/fasttext.wasm.js",
},
tinyld: {
name: "TinyLD",
link: "https://npmjs.com/package/tinyld",
},
} satisfies Record<string, Licence>,
software: {
"@discordeno/bot": apache("Copyright 2021 - 2023 Discordeno"),
cldpre: apache("Copyright (c) Authors of cldpre"),
Expand Down Expand Up @@ -102,10 +134,10 @@ function isValidDictionary(dictionary: string): dictionary is Dictionary {
return dictionary in licences.dictionaries;
}

function getDictionaryLicenceByDictionary(dictionary: Dictionary): DictionaryLicence {
function getDictionaryLicenceByDictionary(dictionary: Dictionary): Licence {
return licences.dictionaries[dictionary];
}

export default licences;
export { isValidDictionary, getDictionaryLicenceByDictionary };
export type { DictionaryLicence };
export type { Licence };
2 changes: 2 additions & 0 deletions source/library/adapters/detectors/adapter.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import type { DetectionLanguage } from "logos:constants/languages";
import type { Licence } from "logos:constants/licences.ts";
import type { Client } from "logos/client";
import { Logger } from "logos/logger";

interface SingleDetectionResult {
readonly language: DetectionLanguage;
readonly source: Licence;
}

abstract class DetectorAdapter {
Expand Down
2 changes: 1 addition & 1 deletion source/library/adapters/detectors/cld.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class CLDAdapter extends DetectorAdapter {

const detectedLanguage = getCLDDetectionLanguageByLocale(detectedLocale);

return { language: detectedLanguage };
return { language: detectedLanguage, source: constants.licences.detectors.cld };
}
}

Expand Down
2 changes: 1 addition & 1 deletion source/library/adapters/detectors/eld.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class ELDAdapter extends DetectorAdapter {

const detectedLanguage = getELDDetectionLanguageByLocale(result.language);

return { language: detectedLanguage };
return { language: detectedLanguage, source: constants.licences.detectors.eld };
}
}

Expand Down
2 changes: 1 addition & 1 deletion source/library/adapters/detectors/fasttext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class FastTextAdapter extends DetectorAdapter {

const detectedLanguage = getFastTextDetectionLanguageByLocale(result.alpha3);

return { language: detectedLanguage };
return { language: detectedLanguage, source: constants.licences.detectors.fasttext };
}
}

Expand Down
2 changes: 1 addition & 1 deletion source/library/adapters/detectors/tinyld.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class TinyLDAdapter extends DetectorAdapter {

const detectedLanguage = getTinyLDDetectionLanguageByLocale(detectedLocale);

return { language: detectedLanguage };
return { language: detectedLanguage, source: constants.licences.detectors.tinyld };
}
}

Expand Down
4 changes: 2 additions & 2 deletions source/library/adapters/dictionaries/adapter.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { LearningLanguage } from "logos:constants/languages";
import type { DictionaryLicence } from "logos:constants/licences";
import type { Licence } from "logos:constants/licences";
import type { PartOfSpeech } from "logos:constants/parts-of-speech";
import type { Client } from "logos/client";
import { Logger } from "logos/logger";
Expand Down Expand Up @@ -68,7 +68,7 @@ interface DictionaryEntry {
/** The inflection of the lemma. */
inflectionTable?: InflectionTable;

sources: [link: string, licence: DictionaryLicence][];
sources: [link: string, licence: Licence][];
}

abstract class DictionaryAdapter<DataType = unknown> {
Expand Down
4 changes: 4 additions & 0 deletions source/library/adapters/translators/adapter.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Languages, TranslationLanguage } from "logos:constants/languages";
import type { Licence } from "logos:constants/licences.ts";
import type { Client } from "logos/client";
import { Logger } from "logos/logger";

Expand All @@ -8,6 +9,9 @@ interface TranslationResult {

/** The translation result. */
readonly text: string;

/** The source of the result. */
readonly source: Licence;
}

abstract class TranslatorAdapter<Language extends string = TranslationLanguage> {
Expand Down
2 changes: 1 addition & 1 deletion source/library/adapters/translators/deepl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ class DeepLAdapter extends TranslatorAdapter<DeepLLanguage> {
? getDeepLTranslationLanguageByLocale(detectedSourceLocale)
: undefined;

return { detectedSourceLanguage, text: translation.text };
return { detectedSourceLanguage, text: translation.text, source: constants.licences.translators.deepl };
}
}

Expand Down
2 changes: 1 addition & 1 deletion source/library/adapters/translators/google-translate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ class GoogleTranslateAdapter extends TranslatorAdapter<GoogleTranslateLanguage>
? undefined
: getGoogleTranslateLanguageByLocale(detectedSourceLocale);

return { detectedSourceLanguage, text: translatedText };
return { detectedSourceLanguage, text: translatedText, source: constants.licences.translators.googleTranslate };
}
}

Expand Down
2 changes: 1 addition & 1 deletion source/library/adapters/translators/lingvanex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class LingvanexAdapter extends TranslatorAdapter<LingvanexLanguage> {
? undefined
: getLingvanexTranslationLanguageByLocale(detectedSourceLocale);

return { detectedSourceLanguage, text: translatedText };
return { detectedSourceLanguage, text: translatedText, source: constants.licences.translators.lingvanex };
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { Licence } from "logos:constants/licences.ts";
import type { Client } from "logos/client.ts";
import { SourceNotice } from "logos/commands/components/source-notices/source-notice.ts";

class RecognitionSourceNotice extends SourceNotice {
constructor(client: Client, { interaction, sources }: { interaction: Logos.Interaction; sources: Licence[] }) {
const strings = constants.contexts.recognitionsMadeBy({
localise: client.localise.bind(client),
locale: interaction.displayLocale,
});

super(client, {
interaction,
sources: sources.map((source) => `[${source.name}](${source.link})`),
notice: strings.recognitionsMadeBy,
});
}
}

export { RecognitionSourceNotice };
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ abstract class SourceNotice {
readonly #buttonPresses: InteractionCollector;
readonly #interaction: Logos.Interaction;
readonly #sources: string[];
readonly #notice: string;
readonly #notice?: string;

get button(): Discord.ButtonComponent {
const strings = constants.contexts.source({
Expand All @@ -25,7 +25,7 @@ abstract class SourceNotice {

constructor(
client: Client,
{ interaction, sources, notice }: { interaction: Logos.Interaction; sources: string[]; notice: string },
{ interaction, sources, notice }: { interaction: Logos.Interaction; sources: string[]; notice?: string },
) {
this.client = client;

Expand All @@ -45,7 +45,7 @@ abstract class SourceNotice {
{
description: `${constants.emojis.link} ${sourcesFormatted}`,
color: constants.colours.blue,
footer: { text: this.#notice },
footer: this.#notice !== undefined ? { text: this.#notice } : undefined,
},
],
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { SourceNotice } from "logos/commands/components/source-notices/source-notice.ts";
import type { Client } from "logos/client.ts";
import { SourceNotice } from "logos/commands/components/source-notices/source-notice.ts";

class TatoebaSourceNotice extends SourceNotice {
constructor(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import type { Licence } from "logos:constants/licences.ts";
import type { Client } from "logos/client.ts";
import { SourceNotice } from "logos/commands/components/source-notices/source-notice.ts";

class TranslationSourceNotice extends SourceNotice {
constructor(client: Client, { interaction, source }: { interaction: Logos.Interaction; source: Licence }) {
const strings = constants.contexts.translationsSourcedFrom({
localise: client.localise.bind(client),
locale: interaction.displayLocale,
});

super(client, {
interaction,
sources: [strings.sourcedFrom({ source: `[${source.name}](${source.link})` })],
});
}
}

export { TranslationSourceNotice };
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { SourceNotice } from "logos/commands/components/source-notices/source-notice.ts";
import type { Client } from "logos/client.ts";
import { SourceNotice } from "logos/commands/components/source-notices/source-notice.ts";

class WordSourceNotice extends SourceNotice {
constructor(client: Client, { interaction, sources }: { interaction: Logos.Interaction; sources: string[] }) {
Expand Down
2 changes: 1 addition & 1 deletion source/library/commands/handlers/game.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import { capitalise } from "logos:core/formatting";
import * as levenshtein from "fastest-levenshtein";
import type { Client } from "logos/client";
import { InteractionCollector } from "logos/collectors";
import { TatoebaSourceNotice } from "logos/commands/components/source-notices/tatoeba-source-notice.ts";
import { GuildStatistics } from "logos/models/guild-statistics";
import { User } from "logos/models/user";
import type { SentencePair } from "logos/stores/volatile";
import { TatoebaSourceNotice } from "logos/commands/components/source-notices/tatoeba-source-notice.ts";

function random(max: number): number {
return Math.floor(Math.random() * max);
Expand Down
6 changes: 3 additions & 3 deletions source/library/commands/handlers/licence/dictionary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,14 @@ async function handleDisplayDictionaryLicence(
iconUrl: licence.faviconLink,
url: licence.link,
},
description: `*${licence.notices.licence}*`,
image: licence.notices.badgeLink !== undefined ? { url: licence.notices.badgeLink } : undefined,
description: licence.notices !== undefined ? `*${licence.notices.licence}*` : undefined,
image: licence.notices?.badgeLink !== undefined ? { url: licence.notices.badgeLink } : undefined,
fields: [
{
name: strings.fields.source,
value: licence.link,
},
...(licence.notices.copyright !== undefined
...(licence.notices?.copyright !== undefined
? [
{
name: strings.fields.copyright,
Expand Down
28 changes: 26 additions & 2 deletions source/library/commands/handlers/recognise.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { DetectionLanguage } from "logos:constants/languages";
import { list } from "logos:core/formatting";
import type { Client } from "logos/client";
import { RecognitionSourceNotice } from "logos/commands/components/source-notices/recognition-notice.ts";

async function handleRecogniseLanguageChatInput(
client: Client,
Expand Down Expand Up @@ -69,6 +70,10 @@ async function handleRecogniseLanguage(
return;
}

const sourceNotice = new RecognitionSourceNotice(client, { interaction, sources: detectedLanguages.sources });

await sourceNotice.register();

if (detectedLanguages.likely.length === 1 && detectedLanguages.possible.length === 0) {
const language = detectedLanguages.likely.at(0) as DetectionLanguage | undefined;
if (language === undefined) {
Expand All @@ -79,8 +84,19 @@ async function handleRecogniseLanguage(
...constants.contexts.likelyMatch({ localise: client.localise.bind(client), locale: interaction.locale }),
...constants.contexts.language({ localise: client.localise.bind(client), locale: interaction.locale }),
};

await client.noticed(interaction, {
description: strings.description({ language: strings.language(language) }),
embeds: [
{
description: strings.description({ language: strings.language(language) }),
},
],
components: [
{
type: Discord.MessageComponentTypes.ActionRow,
components: [sourceNotice.button],
},
],
});
return;
}
Expand Down Expand Up @@ -160,7 +176,15 @@ async function handleRecogniseLanguage(
});
}

await client.noticed(interaction, { fields });
await client.noticed(interaction, {
embeds: [{ fields }],
components: [
{
type: Discord.MessageComponentTypes.ActionRow,
components: [sourceNotice.button],
},
],
});
}
}

Expand Down
24 changes: 16 additions & 8 deletions source/library/commands/handlers/translate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import languages, {
import { trim } from "logos:core/formatting";
import type { TranslationResult } from "logos/adapters/translators/adapter";
import type { Client } from "logos/client";
import { TranslationSourceNotice } from "logos/commands/components/source-notices/translation-source-notice.ts";

async function handleTranslateChatInputAutocomplete(
client: Client,
Expand Down Expand Up @@ -336,14 +337,21 @@ async function translateText(
];
}

const components: Discord.ActionRow[] | undefined = interaction.parameters.show
? undefined
: [
{
type: Discord.MessageComponentTypes.ActionRow,
components: [client.interactionRepetitionService.getShowButton(interaction)],
},
];
const sourceNotice = new TranslationSourceNotice(client, { interaction, source: translation.source });

await sourceNotice.register();

const components: Discord.ActionRow[] = [
{
type: Discord.MessageComponentTypes.ActionRow,
components: [
...(interaction.parameters.show
? []
: [client.interactionRepetitionService.getShowButton(interaction)]),
sourceNotice.button,
] as [Discord.ButtonComponent],
},
];

await client.noticed(interaction, { embeds, components });
}
Expand Down
Loading

0 comments on commit 10c397f

Please sign in to comment.