Skip to content

Add German localization #430

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 21 commits into from
Apr 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
c20b1c6
Fixed data collection for Lua comments
SommerEngineering Apr 27, 2025
8f27281
Enhance localization support by adding namespace and type parameters …
SommerEngineering Apr 27, 2025
18aadeb
Refactor IDisposable implementation in MSGComponentBase to improve re…
SommerEngineering Apr 27, 2025
989fb05
Fixed order of initialization
SommerEngineering Apr 27, 2025
ae0cb4c
Added missed text content
SommerEngineering Apr 27, 2025
8896a3c
Added more dialogs & components
SommerEngineering Apr 27, 2025
ea7a899
Updated
SommerEngineering Apr 27, 2025
1a59df8
Added German translation
SommerEngineering Apr 27, 2025
3f2b851
Added abbreviation for TB in code style settings
SommerEngineering Apr 27, 2025
09d87d2
Updated
SommerEngineering Apr 27, 2025
b1c0cb3
Remove generic suffix from type names in ILangExtensions
SommerEngineering Apr 27, 2025
74f6b07
Update German translations for clarity and consistency
SommerEngineering Apr 27, 2025
ad3c428
Refactor Vision and Home components to initialize items on async load…
SommerEngineering Apr 27, 2025
bcde1c2
Formatting
SommerEngineering Apr 27, 2025
22ce747
Refactor FindAllTextTags method to support multiple start tags and im…
SommerEngineering Apr 27, 2025
dc34028
Remove debug logging for language plugin checks
SommerEngineering Apr 27, 2025
b1319fa
Trigger state update for MudDialog on initialization to update the he…
SommerEngineering Apr 27, 2025
a3a1483
Enhance plugin loading with improved error handling and file reading …
SommerEngineering Apr 27, 2025
2492a58
Improve hot reload logic with enhanced logging and semaphore management
SommerEngineering Apr 27, 2025
ed58bae
Add new UI text entries and improve existing translations for chat co…
SommerEngineering Apr 27, 2025
28d6159
Added missed tooltip to the I18N system
SommerEngineering Apr 27, 2025
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Things we are currently working on:
- [x] ~~Added hot-reload support for plugins ([PR #377](https://github.com/MindWorkAI/AI-Studio/pull/377), [PR #391](https://github.com/MindWorkAI/AI-Studio/pull/391))~~
- [ ] Add support for other languages (I18N) to AI Studio (~~[PR #381](https://github.com/MindWorkAI/AI-Studio/pull/381), [PR #400](https://github.com/MindWorkAI/AI-Studio/pull/400), [PR #404](https://github.com/MindWorkAI/AI-Studio/pull/404), [PR #429](https://github.com/MindWorkAI/AI-Studio/pull/429))~~
- [x] ~~Add an I18N assistant to translate all AI Studio texts to a certain language & culture ([PR #422](https://github.com/MindWorkAI/AI-Studio/pull/422))~~
- [ ] Provide MindWork AI Studio in German ([#31](https://github.com/MindWorkAI/Planning/issues/31))
- [ ] Provide MindWork AI Studio in German ([PR #430](https://github.com/MindWorkAI/AI-Studio/pull/430))
- [ ] Add configuration plugins, which allow pre-defining some LLM providers in organizations
- [ ] Add an app store for plugins, showcasing community-contributed plugins from public GitHub and GitLab repositories. This will enable AI Studio users to discover, install, and update plugins directly within the platform.
- [ ] Add assistant plugins
Expand Down
34 changes: 29 additions & 5 deletions app/Build/Commands/CollectI18NKeysCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,24 +133,48 @@ private string ExportToLuaAssignments(Dictionary<string, string> keyValuePairs)

private List<string> FindAllTextTags(ReadOnlySpan<char> fileContent)
{
const string START_TAG = """
const string START_TAG1 = """
T("
""";

const string START_TAG2 = """
TB("
""";

const string END_TAG = """
")
""";

(int Index, int Len) FindNextStart(ReadOnlySpan<char> content)
{
var startIdx1 = content.IndexOf(START_TAG1);
var startIdx2 = content.IndexOf(START_TAG2);

if (startIdx1 == -1 && startIdx2 == -1)
return (-1, 0);

if (startIdx1 == -1)
return (startIdx2, START_TAG2.Length);

if (startIdx2 == -1)
return (startIdx1, START_TAG1.Length);

if (startIdx1 < startIdx2)
return (startIdx1, START_TAG1.Length);

return (startIdx2, START_TAG2.Length);
}

var matches = new List<string>();
var startIdx = fileContent.IndexOf(START_TAG);
var startIdx = FindNextStart(fileContent);
var content = fileContent;
while (startIdx > -1)
while (startIdx.Index > -1)
{
//
// In some cases, after the initial " there follow more " characters.
// We need to skip them:
//
content = content[(startIdx + START_TAG.Length)..];
content = content[(startIdx.Index + startIdx.Len)..];
while(content[0] == '"')
content = content[1..];

Expand All @@ -163,7 +187,7 @@ private List<string> FindAllTextTags(ReadOnlySpan<char> fileContent)
match = match[..^1];

matches.Add(match.ToString());
startIdx = content.IndexOf(START_TAG);
startIdx = FindNextStart(content);
}

return matches;
Expand Down
1 change: 1 addition & 0 deletions app/MindWork AI Studio.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=OS/@EntryIndexedValue">OS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RAG/@EntryIndexedValue">RAG</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RID/@EntryIndexedValue">RID</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TB/@EntryIndexedValue">TB</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=UI/@EntryIndexedValue">UI</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=URL/@EntryIndexedValue">URL</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=I18N/@EntryIndexedValue">I18N</s:String>
Expand Down
10 changes: 5 additions & 5 deletions app/MindWork AI Studio/Assistants/AssistantBase.razor
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
</MudButton>
@if (this.isProcessing && this.cancellationTokenSource is not null)
{
<MudTooltip Text="Stop generation">
<MudTooltip Text="@TB("Stop generation")">
<MudIconButton Variant="Variant.Filled" Icon="@Icons.Material.Filled.Stop" Color="Color.Error" OnClick="() => this.CancelStreaming()"/>
</MudTooltip>
}
Expand Down Expand Up @@ -80,7 +80,7 @@
{
@if (this.ShowSendTo)
{
<MudMenu AnchorOrigin="Origin.TopLeft" TransformOrigin="Origin.BottomLeft" StartIcon="@Icons.Material.Filled.Apps" EndIcon="@Icons.Material.Filled.KeyboardArrowDown" Label="Send to ..." Variant="Variant.Filled" Style="@this.GetSendToColor()" Class="rounded">
<MudMenu AnchorOrigin="Origin.TopLeft" TransformOrigin="Origin.BottomLeft" StartIcon="@Icons.Material.Filled.Apps" EndIcon="@Icons.Material.Filled.KeyboardArrowDown" Label="@TB("Send to ...")" Variant="Variant.Filled" Style="@this.GetSendToColor()" Class="rounded">
@foreach (var assistant in Enum.GetValues<Components>().Where(n => n.AllowSendTo()).OrderBy(n => n.Name().Length))
{
<MudMenuItem OnClick="() => this.SendToAssistant(assistant, new())">
Expand Down Expand Up @@ -110,7 +110,7 @@
break;

case SendToButton sendToButton:
<MudMenu AnchorOrigin="Origin.TopLeft" TransformOrigin="Origin.BottomLeft" StartIcon="@Icons.Material.Filled.Apps" EndIcon="@Icons.Material.Filled.KeyboardArrowDown" Label="Send to ..." Variant="Variant.Filled" Style="@this.GetSendToColor()" Class="rounded">
<MudMenu AnchorOrigin="Origin.TopLeft" TransformOrigin="Origin.BottomLeft" StartIcon="@Icons.Material.Filled.Apps" EndIcon="@Icons.Material.Filled.KeyboardArrowDown" Label="@TB("Send to ...")" Variant="Variant.Filled" Style="@this.GetSendToColor()" Class="rounded">
@foreach (var assistant in Enum.GetValues<Components>().Where(n => n.AllowSendTo()).OrderBy(n => n.Name().Length))
{
<MudMenuItem OnClick="() => this.SendToAssistant(assistant, sendToButton)">
Expand All @@ -125,14 +125,14 @@
@if (this.ShowCopyResult)
{
<MudButton Variant="Variant.Filled" StartIcon="@Icons.Material.Filled.ContentCopy" OnClick="() => this.CopyToClipboard()">
Copy result
@TB("Copy result")
</MudButton>
}

@if (this.ShowReset)
{
<MudButton Variant="Variant.Filled" Style="@this.GetResetColor()" StartIcon="@Icons.Material.Filled.Refresh" OnClick="() => this.InnerResetForm()">
Reset
@TB("Reset")
</MudButton>
}

Expand Down
5 changes: 4 additions & 1 deletion app/MindWork AI Studio/Assistants/AssistantBase.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ public abstract partial class AssistantBase<TSettings> : AssistantLowerBase wher

protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();

this.formChangeTimer.AutoReset = false;
this.formChangeTimer.Elapsed += async (_, _) =>
{
Expand All @@ -113,7 +115,6 @@ protected override async Task OnInitializedAsync()
this.MightPreselectValues();
this.providerSettings = this.SettingsManager.GetPreselectedProvider(this.Component);
this.currentProfile = this.SettingsManager.GetPreselectedProfile(this.Component);
await base.OnInitializedAsync();
}

protected override async Task OnParametersSetAsync()
Expand All @@ -136,6 +137,8 @@ protected override async Task OnAfterRenderAsync(bool firstRender)

#endregion

private string TB(string fallbackEN) => this.T(fallbackEN, typeof(AssistantBase<TSettings>).Namespace, nameof(AssistantBase<TSettings>));

private string SubmitButtonStyle => this.SettingsManager.ConfigurationData.LLMProviders.ShowProviderConfidence ? this.providerSettings.UsedLLMProvider.GetConfidence(this.SettingsManager).StyleBorder(this.SettingsManager) : string.Empty;

protected string? ValidatingProvider(AIStudio.Settings.Provider provider)
Expand Down
22 changes: 18 additions & 4 deletions app/MindWork AI Studio/Assistants/I18N/AssistantI18N.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,23 @@ private async Task LocalizeTextContent()
if(this.cancellationTokenSource!.IsCancellationRequested)
return;

// Phase 2: Create the Lua code
this.Phase2CreateLuaCode();
//
// Phase 2: Create the Lua code. We want to use the base language
// for the comments, though:
//
var commentContent = new Dictionary<string, string>(this.addedContent);
foreach (var keyValuePair in PluginFactory.BaseLanguage.Content)
{
if (this.cancellationTokenSource!.IsCancellationRequested)
break;

if (this.removedContent.ContainsKey(keyValuePair.Key))
continue;

commentContent.TryAdd(keyValuePair.Key, keyValuePair.Value);
}

this.Phase2CreateLuaCode(commentContent);
}

private async Task Phase1TranslateAddedContent()
Expand Down Expand Up @@ -346,10 +361,9 @@ private async Task Phase1TranslateAddedContent()
}
}

private void Phase2CreateLuaCode()
private void Phase2CreateLuaCode(IReadOnlyDictionary<string, string> commentContent)
{
this.finalLuaCode.Clear();
var commentContent = this.addedContent.Concat(PluginFactory.BaseLanguage.Content).ToDictionary();
LuaTable.Create(ref this.finalLuaCode, "UI_TEXT_CONTENT", this.localizedContent, commentContent, this.cancellationTokenSource!.Token);

// Next, we must remove the `root::` prefix from the keys:
Expand Down
Loading