Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import Component from "@glimmer/component";
import { i18n } from "discourse-i18n";
import DTooltip from "float-kit/components/d-tooltip";

export default class TranslatedPostIndicator extends Component {
get tooltip() {
return i18n("translator.originally_written_in", {
language: this.args.data.detectedLanguage,
});
}

<template>
<DTooltip
@identifier="discourse-translator_translated-post-indicator"
@icon="language"
@content={{this.tooltip}}
/>
Comment on lines +13 to +17
Copy link
Contributor Author

@nattsw nattsw Apr 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had considered just using {{icon "language" title="something"}} but it looks like the title will always be i18n-ified.

</template>
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { withPluginApi } from "discourse/lib/plugin-api";
import RenderGlimmer from "discourse/widgets/render-glimmer";
import LanguageSwitcher from "../components/language-switcher";
import ToggleTranslationButton from "../components/post-menu/toggle-translation-button";
import ShowOriginalContent from "../components/show-original-content";
import TranslatedPost from "../components/translated-post";
import TranslatedPostIndicator from "../components/translated-post-indicator";

function initializeTranslation(api) {
const siteSettings = api.container.lookup("service:site-settings");
Expand Down Expand Up @@ -46,6 +48,18 @@ function initializeTranslation(api) {
});
}
);

api.includePostAttributes("is_translated", "detected_language");
api.decorateWidget("post-date:before", (dec) => {
if (dec.attrs.is_translated && dec.attrs.detected_language) {
return new RenderGlimmer(
dec.widget,
"div.post-info.post-translated-indicator",
TranslatedPostIndicator,
{ detectedLanguage: dec.attrs.detected_language }
);
}
});
}

customizePostMenu(api);
Expand Down
8 changes: 8 additions & 0 deletions assets/stylesheets/common/common.scss
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,11 @@
color: var(--tertiary);
}
}

.post-info .post-info.post-translated-indicator {
display: inline;

svg {
color: var(--primary-med-or-secondary-med);
}
}
1 change: 1 addition & 0 deletions config/locales/client.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ en:
content_translated: "Page is machine-translated. Click to view original"
translated_from: "Translated from %{language} by %{translator}"
translating: "Translating"
originally_written_in: "This post was originally written in %{language}"
7 changes: 7 additions & 0 deletions lib/discourse_translator/inline_translation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,16 @@ def inject(plugin)
plugin.add_to_serializer(:basic_post, :is_translated) do
SiteSetting.experimental_inline_translation &&
!object.locale_matches?(InlineTranslation.effective_locale) &&
!scope&.request&.cookies&.key?(SHOW_ORIGINAL_COOKIE) &&
object.translation_for(InlineTranslation.effective_locale).present?
end

plugin.add_to_serializer(:basic_post, :detected_language) do
if SiteSetting.experimental_inline_translation && object.detected_locale.present?
LocaleToLanguage.get_language(object.detected_locale)
end
end

plugin.add_to_serializer(:topic_view, :is_translated) do
SiteSetting.experimental_inline_translation &&
!object.topic.locale_matches?(InlineTranslation.effective_locale) &&
Expand Down
9 changes: 9 additions & 0 deletions lib/discourse_translator/locale_to_language.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

module DiscourseTranslator
class LocaleToLanguage
def self.get_language(locale)
LocaleSiteSetting.values.find { |v| v[:value] == locale.to_s.sub("-", "_") }&.[](:name)
end
end
end
18 changes: 18 additions & 0 deletions spec/lib/locale_to_language_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# frozen_string_literal: true

describe DiscourseTranslator::LocaleToLanguage do
describe ".get_language" do
it "returns the language name for a valid locale" do
expect(DiscourseTranslator::LocaleToLanguage.get_language("en")).to eq("English (US)")
expect(DiscourseTranslator::LocaleToLanguage.get_language("es")).to eq("Español")
end

it "returns nil for a locale that doesn't exist" do
expect(DiscourseTranslator::LocaleToLanguage.get_language("xx")).to be_nil
end

it "handles symbol locales" do
expect(DiscourseTranslator::LocaleToLanguage.get_language(:en_GB)).to eq("English (UK)")
end
end
end
11 changes: 11 additions & 0 deletions spec/system/full_page_translation_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
fab!(:post_2) do
Fabricate(:post, topic: topic, raw: "The greatest victory is that which requires no battle")
end
fab!(:post_3) { Fabricate(:post, topic: topic, raw: "将とは、智・信・仁・勇・厳なり。") }

let(:topic_page) { PageObjects::Pages::Topic.new }
let(:topic_list) { PageObjects::Components::TopicList.new }
Expand All @@ -21,11 +22,13 @@
topic.set_detected_locale("en")
post_1.set_detected_locale("en")
post_2.set_detected_locale("en")
post_3.set_detected_locale("ja")

topic.set_translation("ja", "孫子兵法からの人生戦略")
topic.set_translation("es", "Estrategias de vida de El arte de la guerra")
post_1.set_translation("ja", "傑作は単なる軍事戦略についてではありません")
post_2.set_translation("ja", "最大の勝利は戦いを必要としないものです")
post_3.set_translation("en", "A general is one who possesses wisdom, sincerity...")
end

context "when the feature is enabled" do
Expand All @@ -37,6 +40,7 @@
SiteSetting.experimental_inline_translation = true
SiteSetting.automatic_translation_backfill_rate = 1
SiteSetting.automatic_translation_target_languages = "ja"
SiteSetting.experimental_anon_language_switcher = true
end

it "shows the correct language based on the selected language and login status" do
Expand All @@ -49,6 +53,13 @@
expect(find(topic_page.post_by_number_selector(1))).to have_content(
"The masterpiece isn’t just about military strategy",
)
expect(find(topic_page.post_by_number_selector(3))).to have_css(
"div.post-translated-indicator",
)
find("#{topic_page.post_by_number_selector(3)} .post-translated-indicator").hover
expect(
PageObjects::Components::Tooltips.new("discourse-translator_translated-post-indicator"),
).to be_present(text: "This post was originally written in 日本語")

sign_in(japanese_user)
visit("/")
Expand Down
Loading