mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-10-21 23:38:00 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b9416e66c3 | ||
|
|
9f576e8572 | ||
|
|
629613f75a | ||
|
|
abbb8c1650 | ||
|
|
d2ac4e26b0 | ||
|
|
bd97c0fb4b | ||
|
|
8bd54e6d61 | ||
|
|
e419c5561b | ||
|
|
24a73e92e1 | ||
|
|
832e054dbf | ||
|
|
4703ab04ab | ||
|
|
c1d5be63cc | ||
|
|
5d3ea3d57a | ||
|
|
217b9c4db3 | ||
|
|
e9c805f0df | ||
|
|
11475ea4af | ||
|
|
46a7e98141 | ||
|
|
0d6ccbd237 | ||
|
|
efb30cad87 | ||
|
|
fe33867cb6 | ||
|
|
1b1989e8eb | ||
|
|
afa5df894e | ||
|
|
c8d67b1e4c | ||
|
|
e717b84fb4 | ||
|
|
2463c85b77 | ||
|
|
cbf34580b3 | ||
|
|
e60f815d77 | ||
|
|
a19a6b2188 | ||
|
|
d2dd90d089 | ||
|
|
37e113af0e |
No files matched your search
@@ -11,3 +11,7 @@ media/**/*.pptx filter=lfs diff=lfs merge=lfs -text
|
|||||||
media/**/*.png filter=lfs diff=lfs merge=lfs -text
|
media/**/*.png filter=lfs diff=lfs merge=lfs -text
|
||||||
media/**/*.ico filter=lfs diff=lfs merge=lfs -text
|
media/**/*.ico filter=lfs diff=lfs merge=lfs -text
|
||||||
media/**/*.icns filter=lfs diff=lfs merge=lfs -text
|
media/**/*.icns filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.woff2 filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.afpub filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.afdesign filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.afphoto filter=lfs diff=lfs merge=lfs -text
|
||||||
@@ -278,7 +278,7 @@ jobs:
|
|||||||
if: matrix.platform != 'windows-latest'
|
if: matrix.platform != 'windows-latest'
|
||||||
run: |
|
run: |
|
||||||
if ! cargo tauri --version > /dev/null 2>&1; then
|
if ! cargo tauri --version > /dev/null 2>&1; then
|
||||||
cargo install tauri-cli
|
cargo install --version 1.6.2 tauri-cli
|
||||||
else
|
else
|
||||||
echo "Tauri is already installed"
|
echo "Tauri is already installed"
|
||||||
fi
|
fi
|
||||||
@@ -287,7 +287,7 @@ jobs:
|
|||||||
if: matrix.platform == 'windows-latest'
|
if: matrix.platform == 'windows-latest'
|
||||||
run: |
|
run: |
|
||||||
if (-not (cargo tauri --version 2>$null)) {
|
if (-not (cargo tauri --version 2>$null)) {
|
||||||
cargo install tauri-cli
|
cargo install --version 1.6.2 tauri-cli
|
||||||
} else {
|
} else {
|
||||||
Write-Output "Tauri is already installed"
|
Write-Output "Tauri is already installed"
|
||||||
}
|
}
|
||||||
@@ -500,7 +500,7 @@ jobs:
|
|||||||
apt-get install --yes libwebkit2gtk-4.0-dev build-essential libssl-dev libgtk-3-dev libayatana-appindicator3-dev librsvg2-dev
|
apt-get install --yes libwebkit2gtk-4.0-dev build-essential libssl-dev libgtk-3-dev libayatana-appindicator3-dev librsvg2-dev
|
||||||
|
|
||||||
# Setup Tauri:
|
# Setup Tauri:
|
||||||
cargo install tauri-cli
|
cargo install --version 1.6.2 tauri-cli
|
||||||
|
|
||||||
- name: Add the built runner image to the cache
|
- name: Add the built runner image to the cache
|
||||||
if: ${{ steps.linux_arm_cache.outputs.cache-hit != 'true' && env.SKIP != 'true' }}
|
if: ${{ steps.linux_arm_cache.outputs.cache-hit != 'true' && env.SKIP != 'true' }}
|
||||||
|
|||||||
@@ -1,4 +1,30 @@
|
|||||||
# MindWork AI Studio
|
# MindWork AI Studio
|
||||||
|
|
||||||
|
## News
|
||||||
|
Things we are currently working on:
|
||||||
|
|
||||||
|
- Since September 2024: Experiments have been started on how we can work on long texts with AI Studio. Let's say you want to write a fantasy novel or create a complex project proposal and use LLM for support. The initial experiments were promising, but not yet satisfactory. We are testing further approaches until a satisfactory solution is found. Related PR: [#167](https://github.com/MindWorkAI/AI-Studio/pull/167).
|
||||||
|
|
||||||
|
|
||||||
|
Other News:
|
||||||
|
|
||||||
|
- October 2024: We've found the first two financial supporters. Huge thanks to `richard-stanton` and `peerschuett` for backing the project. Thanks for having the courage to be the first to support us.
|
||||||
|
|
||||||
|
- October 2024: The [German Aerospace Center (DLR)](https://en.wikipedia.org/wiki/German_Aerospace_Center) ([Website](https://www.dlr.de/en)) will use AI Studio at least within the scope of one project and will also contribute to its further development. This is great news.
|
||||||
|
|
||||||
|
|
||||||
|
Features we have recently released:
|
||||||
|
|
||||||
|
- v0.9.17: Added the new Anthropic model `claude-3-5-sonnet-20241022`.
|
||||||
|
- v0.9.16: Added workspace display options & improved the layout of the app window.
|
||||||
|
- v0.9.15: Added the bias-of-the-day assistant. Tells you about a cognitive bias every day.
|
||||||
|
- v0.9.13: You can use `ollama` providers secured with API keys.
|
||||||
|
- v0.9.12: Added a job posting assistant to the business category and improved grammar & spelling check and rewrite assistants.
|
||||||
|
- v0.9.11: Added enforcement of minimal confidence levels & dark mode.
|
||||||
|
- v0.9.10: Added support for the OpenAI `o1` model.
|
||||||
|
|
||||||
|
## What is AI Studio?
|
||||||
|
|
||||||

|

|
||||||

|

|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
|
||||||
<configuration default="false" name="AI Studio" type="DotNetProject" factoryName=".NET Project">
|
|
||||||
<option name="EXE_PATH" value="$PROJECT_DIR$/MindWork AI Studio/bin/Debug/net8.0/osx-arm64/mindworkAIStudio.dll" />
|
|
||||||
<option name="PROGRAM_PARAMETERS" value="" />
|
|
||||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/MindWork AI Studio" />
|
|
||||||
<option name="PASS_PARENT_ENVS" value="1" />
|
|
||||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
|
||||||
<option name="USE_MONO" value="0" />
|
|
||||||
<option name="RUNTIME_ARGUMENTS" value="" />
|
|
||||||
<option name="RUNTIME_TYPE" value="coreclr" />
|
|
||||||
<option name="PROJECT_PATH" value="$PROJECT_DIR$/MindWork AI Studio/MindWork AI Studio.csproj" />
|
|
||||||
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
|
|
||||||
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
|
||||||
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
|
||||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
|
||||||
<option name="PROJECT_TFM" value="net8.0" />
|
|
||||||
<method v="2">
|
|
||||||
<option name="Build" />
|
|
||||||
</method>
|
|
||||||
</configuration>
|
|
||||||
</component>
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
|
||||||
<configuration default="false" name="Run Dev" type="CompoundRunConfigurationType">
|
|
||||||
<toRun name="AI Studio" type="DotNetProject" />
|
|
||||||
<toRun name="Tauri Dev" type="ShConfigurationType" />
|
|
||||||
<method v="2" />
|
|
||||||
</configuration>
|
|
||||||
</component>
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
*.woff2 filter=lfs diff=lfs merge=lfs -text
|
|
||||||
@@ -48,17 +48,17 @@
|
|||||||
|
|
||||||
@if (!this.FooterButtons.Any(x => x.Type is ButtonTypes.SEND_TO))
|
@if (!this.FooterButtons.Any(x => x.Type is ButtonTypes.SEND_TO))
|
||||||
{
|
{
|
||||||
<MudMenu StartIcon="@Icons.Material.Filled.Apps" EndIcon="@Icons.Material.Filled.KeyboardArrowDown" Label="Send to ..." Variant="Variant.Filled" Style="@this.GetSendToColor()" Class="rounded">
|
@if (this.ShowSendTo)
|
||||||
@foreach (var assistant in Enum.GetValues<Components>().OrderBy(n => n.Name().Length))
|
{
|
||||||
{
|
<MudMenu StartIcon="@Icons.Material.Filled.Apps" EndIcon="@Icons.Material.Filled.KeyboardArrowDown" Label="Send to ..." Variant="Variant.Filled" Style="@this.GetSendToColor()" Class="rounded">
|
||||||
if (assistant is Components.NONE || this.Component == assistant)
|
@foreach (var assistant in Enum.GetValues<Components>().Where(n => n.AllowSendTo()).OrderBy(n => n.Name().Length))
|
||||||
continue;
|
{
|
||||||
|
<MudMenuItem OnClick="() => this.SendToAssistant(assistant, new())">
|
||||||
<MudMenuItem OnClick="() => this.SendToAssistant(assistant, new())">
|
@assistant.Name()
|
||||||
@assistant.Name()
|
</MudMenuItem>
|
||||||
</MudMenuItem>
|
}
|
||||||
}
|
</MudMenu>
|
||||||
</MudMenu>
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@foreach (var button in this.FooterButtons)
|
@foreach (var button in this.FooterButtons)
|
||||||
@@ -81,11 +81,8 @@
|
|||||||
|
|
||||||
case SendToButton sendToButton:
|
case SendToButton sendToButton:
|
||||||
<MudMenu StartIcon="@Icons.Material.Filled.Apps" EndIcon="@Icons.Material.Filled.KeyboardArrowDown" Label="Send to ..." Variant="Variant.Filled" Style="@this.GetSendToColor()" Class="rounded">
|
<MudMenu StartIcon="@Icons.Material.Filled.Apps" EndIcon="@Icons.Material.Filled.KeyboardArrowDown" Label="Send to ..." Variant="Variant.Filled" Style="@this.GetSendToColor()" Class="rounded">
|
||||||
@foreach (var assistant in Enum.GetValues<Components>().OrderBy(n => n.Name().Length))
|
@foreach (var assistant in Enum.GetValues<Components>().Where(n => n.AllowSendTo()).OrderBy(n => n.Name().Length))
|
||||||
{
|
{
|
||||||
if(assistant is Components.NONE || sendToButton.Self == assistant)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
<MudMenuItem OnClick="() => this.SendToAssistant(assistant, sendToButton)">
|
<MudMenuItem OnClick="() => this.SendToAssistant(assistant, sendToButton)">
|
||||||
@assistant.Name()
|
@assistant.Name()
|
||||||
</MudMenuItem>
|
</MudMenuItem>
|
||||||
@@ -95,13 +92,19 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<MudButton Variant="Variant.Filled" StartIcon="@Icons.Material.Filled.ContentCopy" OnClick="() => this.CopyToClipboard()">
|
@if (this.ShowCopyResult)
|
||||||
Copy result
|
{
|
||||||
</MudButton>
|
<MudButton Variant="Variant.Filled" StartIcon="@Icons.Material.Filled.ContentCopy" OnClick="() => this.CopyToClipboard()">
|
||||||
|
Copy result
|
||||||
<MudButton Variant="Variant.Filled" Style="@this.GetResetColor()" StartIcon="@Icons.Material.Filled.Refresh" OnClick="() => this.InnerResetForm()">
|
</MudButton>
|
||||||
Reset
|
}
|
||||||
</MudButton>
|
|
||||||
|
@if (this.ShowReset)
|
||||||
|
{
|
||||||
|
<MudButton Variant="Variant.Filled" Style="@this.GetResetColor()" StartIcon="@Icons.Material.Filled.Refresh" OnClick="() => this.InnerResetForm()">
|
||||||
|
Reset
|
||||||
|
</MudButton>
|
||||||
|
}
|
||||||
|
|
||||||
@if (this.SettingsManager.ConfigurationData.LLMProviders.ShowProviderConfidence)
|
@if (this.SettingsManager.ConfigurationData.LLMProviders.ShowProviderConfidence)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -74,6 +74,12 @@ public abstract partial class AssistantBase : ComponentBase, IMessageBusReceiver
|
|||||||
protected virtual bool ShowProfileSelection => true;
|
protected virtual bool ShowProfileSelection => true;
|
||||||
|
|
||||||
protected virtual bool ShowDedicatedProgress => false;
|
protected virtual bool ShowDedicatedProgress => false;
|
||||||
|
|
||||||
|
protected virtual bool ShowSendTo => true;
|
||||||
|
|
||||||
|
protected virtual bool ShowCopyResult => true;
|
||||||
|
|
||||||
|
protected virtual bool ShowReset => true;
|
||||||
|
|
||||||
protected virtual ChatThread ConvertToChatThread => this.chatThread ?? new();
|
protected virtual ChatThread ConvertToChatThread => this.chatThread ?? new();
|
||||||
|
|
||||||
@@ -173,14 +179,36 @@ public abstract partial class AssistantBase : ComponentBase, IMessageBusReceiver
|
|||||||
Blocks = [],
|
Blocks = [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Guid CreateChatThread(Guid workspaceId, string name)
|
||||||
|
{
|
||||||
|
var chatId = Guid.NewGuid();
|
||||||
|
this.chatThread = new()
|
||||||
|
{
|
||||||
|
WorkspaceId = workspaceId,
|
||||||
|
ChatId = chatId,
|
||||||
|
Name = name,
|
||||||
|
Seed = this.RNG.Next(),
|
||||||
|
SystemPrompt = !this.AllowProfiles ? this.SystemPrompt :
|
||||||
|
$"""
|
||||||
|
{this.SystemPrompt}
|
||||||
|
|
||||||
|
{this.currentProfile.ToSystemPrompt()}
|
||||||
|
""",
|
||||||
|
Blocks = [],
|
||||||
|
};
|
||||||
|
|
||||||
|
return chatId;
|
||||||
|
}
|
||||||
|
|
||||||
protected DateTimeOffset AddUserRequest(string request)
|
protected DateTimeOffset AddUserRequest(string request, bool hideContentFromUser = false)
|
||||||
{
|
{
|
||||||
var time = DateTimeOffset.Now;
|
var time = DateTimeOffset.Now;
|
||||||
this.chatThread!.Blocks.Add(new ContentBlock
|
this.chatThread!.Blocks.Add(new ContentBlock
|
||||||
{
|
{
|
||||||
Time = time,
|
Time = time,
|
||||||
ContentType = ContentType.TEXT,
|
ContentType = ContentType.TEXT,
|
||||||
|
HideFromUser = hideContentFromUser,
|
||||||
Role = ChatRole.USER,
|
Role = ChatRole.USER,
|
||||||
Content = new ContentText
|
Content = new ContentText
|
||||||
{
|
{
|
||||||
@@ -237,9 +265,12 @@ public abstract partial class AssistantBase : ComponentBase, IMessageBusReceiver
|
|||||||
return icon;
|
return icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task SendToAssistant(Tools.Components destination, SendToButton sendToButton)
|
protected Task SendToAssistant(Tools.Components destination, SendToButton sendToButton)
|
||||||
{
|
{
|
||||||
var contentToSend = sendToButton.UseResultingContentBlockData switch
|
if (!destination.AllowSendTo())
|
||||||
|
return Task.CompletedTask;
|
||||||
|
|
||||||
|
var contentToSend = sendToButton == default ? string.Empty : sendToButton.UseResultingContentBlockData switch
|
||||||
{
|
{
|
||||||
false => sendToButton.GetText(),
|
false => sendToButton.GetText(),
|
||||||
true => this.resultingContentBlock?.Content switch
|
true => this.resultingContentBlock?.Content switch
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
@attribute [Route(Routes.ASSISTANT_BIAS)]
|
||||||
|
@inherits AssistantBaseCore
|
||||||
|
|
||||||
|
<MudText Typo="Typo.body1">
|
||||||
|
<b>Links:</b>
|
||||||
|
</MudText>
|
||||||
|
<MudList T="string" Class="mb-6">
|
||||||
|
<MudListItem T="string" Icon="@Icons.Material.Filled.Link" Target="_blank" Href="https://en.wikipedia.org/wiki/List_of_cognitive_biases">Wikipedia list of cognitive biases</MudListItem>
|
||||||
|
<MudListItem T="string" Icon="@Icons.Material.Filled.Link" Target="_blank" Href="https://commons.wikimedia.org/wiki/File:Cognitive_Bias_Codex_With_Definitions_1-2,_an_Extension_of_the_work_of_John_Manoogian_by_Brian_Rene_Morrissette.png">Extended bias poster</MudListItem>
|
||||||
|
<MudListItem T="string" Icon="@Icons.Material.Filled.Link" Target="_blank" Href="https://betterhumans.pub/cognitive-bias-cheat-sheet-55a472476b18">Blog post of Buster Benson: "Cognitive bias cheat sheet"</MudListItem>
|
||||||
|
</MudList>
|
||||||
|
|
||||||
|
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelecting())" @bind-Value="@this.selectedTargetLanguage" ValidateSelection="@this.ValidateTargetLanguage" Icon="@Icons.Material.Filled.Translate" Label="Target language" AllowOther="@true" OtherValue="CommonLanguages.OTHER" @bind-OtherInput="@this.customTargetLanguage" ValidateOther="@this.ValidateCustomLanguage" LabelOther="Custom target language" />
|
||||||
|
<ProviderSelection @bind-ProviderSettings="@this.providerSettings" ValidateProvider="@this.ValidatingProvider"/>
|
||||||
@@ -0,0 +1,164 @@
|
|||||||
|
using System.Text;
|
||||||
|
|
||||||
|
using AIStudio.Components;
|
||||||
|
using AIStudio.Settings.DataModel;
|
||||||
|
|
||||||
|
namespace AIStudio.Assistants.BiasDay;
|
||||||
|
|
||||||
|
public partial class BiasOfTheDayAssistant : AssistantBaseCore
|
||||||
|
{
|
||||||
|
public override Tools.Components Component => Tools.Components.BIAS_DAY_ASSISTANT;
|
||||||
|
|
||||||
|
protected override string Title => "Bias of the Day";
|
||||||
|
|
||||||
|
protected override string Description =>
|
||||||
|
"""
|
||||||
|
Learn about a different cognitive bias every day. You can also ask the LLM your questions. The idea behind
|
||||||
|
"Bias of the Day" is based on work by Buster Benson, John Manoogian III, and Brian Rene Morrissette. Buster
|
||||||
|
Benson grouped the biases, and the original texts come from Wikipedia. Brian Rene Morrissette condensed them
|
||||||
|
into a shorter version. Finally, John Manoogian III created the original poster based on Benson's work and
|
||||||
|
Morrissette's texts. Thorsten Sommer compared all texts for integration into AI Studio with the current Wikipedia
|
||||||
|
versions, updated them, and added source references. The idea of learning about one bias each day based on John's
|
||||||
|
poster comes from Drew Nelson.
|
||||||
|
""";
|
||||||
|
|
||||||
|
protected override string SystemPrompt => $"""
|
||||||
|
You are a friendly, helpful expert on cognitive bias. You studied psychology and
|
||||||
|
have a lot of experience. You explain a bias every day. Today's bias belongs to
|
||||||
|
the category: "{this.biasOfTheDay.Category.ToName()}". We have the following
|
||||||
|
thoughts on this category:
|
||||||
|
|
||||||
|
{this.biasOfTheDay.Category.GetThoughts()}
|
||||||
|
|
||||||
|
Today's bias is:
|
||||||
|
{this.biasOfTheDay.Description}
|
||||||
|
{this.SystemPromptSources()}
|
||||||
|
Important: you use the following language: {this.SystemPromptLanguage()}. Please
|
||||||
|
ask the user a personal question at the end to encourage them to think about
|
||||||
|
this bias.
|
||||||
|
""";
|
||||||
|
|
||||||
|
protected override IReadOnlyList<IButtonData> FooterButtons => [];
|
||||||
|
|
||||||
|
protected override string SubmitText => "Show me the bias of the day";
|
||||||
|
|
||||||
|
protected override Func<Task> SubmitAction => this.TellBias;
|
||||||
|
|
||||||
|
protected override bool ShowSendTo => false;
|
||||||
|
|
||||||
|
protected override bool ShowCopyResult => false;
|
||||||
|
|
||||||
|
protected override bool ShowReset => false;
|
||||||
|
|
||||||
|
protected override void ResetFrom()
|
||||||
|
{
|
||||||
|
if (!this.MightPreselectValues())
|
||||||
|
{
|
||||||
|
this.selectedTargetLanguage = CommonLanguages.AS_IS;
|
||||||
|
this.customTargetLanguage = string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool MightPreselectValues()
|
||||||
|
{
|
||||||
|
if (this.SettingsManager.ConfigurationData.BiasOfTheDay.PreselectOptions)
|
||||||
|
{
|
||||||
|
this.selectedTargetLanguage = this.SettingsManager.ConfigurationData.BiasOfTheDay.PreselectedTargetLanguage;
|
||||||
|
this.customTargetLanguage = this.SettingsManager.ConfigurationData.BiasOfTheDay.PreselectedOtherLanguage;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Bias biasOfTheDay = BiasCatalog.NONE;
|
||||||
|
private CommonLanguages selectedTargetLanguage = CommonLanguages.AS_IS;
|
||||||
|
private string customTargetLanguage = string.Empty;
|
||||||
|
|
||||||
|
private string? ValidateTargetLanguage(CommonLanguages language)
|
||||||
|
{
|
||||||
|
if(language is CommonLanguages.AS_IS)
|
||||||
|
return "Please select a target language for the bias.";
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string? ValidateCustomLanguage(string language)
|
||||||
|
{
|
||||||
|
if(this.selectedTargetLanguage == CommonLanguages.OTHER && string.IsNullOrWhiteSpace(language))
|
||||||
|
return "Please provide a custom language.";
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string SystemPromptSources()
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
if (this.biasOfTheDay.Links.Count > 0)
|
||||||
|
{
|
||||||
|
sb.AppendLine();
|
||||||
|
sb.AppendLine("Please share the following sources with the user as a Markdown list:");
|
||||||
|
foreach (var link in this.biasOfTheDay.Links)
|
||||||
|
sb.AppendLine($"- {link}");
|
||||||
|
|
||||||
|
sb.AppendLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private string SystemPromptLanguage()
|
||||||
|
{
|
||||||
|
if(this.selectedTargetLanguage is CommonLanguages.OTHER)
|
||||||
|
return this.customTargetLanguage;
|
||||||
|
|
||||||
|
return this.selectedTargetLanguage.Name();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task TellBias()
|
||||||
|
{
|
||||||
|
bool useDrawnBias = false;
|
||||||
|
if(this.SettingsManager.ConfigurationData.BiasOfTheDay.RestrictOneBiasPerDay)
|
||||||
|
{
|
||||||
|
if(this.SettingsManager.ConfigurationData.BiasOfTheDay.DateLastBiasDrawn == DateOnly.FromDateTime(DateTime.Now))
|
||||||
|
{
|
||||||
|
var biasChat = new LoadChat
|
||||||
|
{
|
||||||
|
WorkspaceId = Workspaces.WORKSPACE_ID_BIAS,
|
||||||
|
ChatId = this.SettingsManager.ConfigurationData.BiasOfTheDay.BiasOfTheDayChatId,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (Workspaces.IsChatExisting(biasChat))
|
||||||
|
{
|
||||||
|
MessageBus.INSTANCE.DeferMessage(this, Event.LOAD_CHAT, biasChat);
|
||||||
|
this.NavigationManager.NavigateTo(Routes.CHAT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
useDrawnBias = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.form!.Validate();
|
||||||
|
if (!this.inputIsValid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.biasOfTheDay = useDrawnBias ?
|
||||||
|
BiasCatalog.ALL_BIAS[this.SettingsManager.ConfigurationData.BiasOfTheDay.BiasOfTheDayId] :
|
||||||
|
BiasCatalog.GetRandomBias(this.SettingsManager.ConfigurationData.BiasOfTheDay.UsedBias);
|
||||||
|
|
||||||
|
var chatId = this.CreateChatThread(Workspaces.WORKSPACE_ID_BIAS, this.biasOfTheDay.Name);
|
||||||
|
this.SettingsManager.ConfigurationData.BiasOfTheDay.BiasOfTheDayId = this.biasOfTheDay.Id;
|
||||||
|
this.SettingsManager.ConfigurationData.BiasOfTheDay.BiasOfTheDayChatId = chatId;
|
||||||
|
this.SettingsManager.ConfigurationData.BiasOfTheDay.DateLastBiasDrawn = DateOnly.FromDateTime(DateTime.Now);
|
||||||
|
await this.SettingsManager.StoreSettings();
|
||||||
|
var time = this.AddUserRequest(
|
||||||
|
"""
|
||||||
|
Please tell me about the bias of the day.
|
||||||
|
""", true);
|
||||||
|
|
||||||
|
// Start the AI response without waiting for it to finish:
|
||||||
|
_ = this.AddAIResponseAsync(time);
|
||||||
|
await this.SendToAssistant(Tools.Components.CHAT, default);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,10 +18,15 @@ public class ContentBlock
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The content of the block.
|
/// The content of the block.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IContent? Content { get; init; } = null;
|
public IContent? Content { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The role of the content block in the chat thread, e.g., user, AI, etc.
|
/// The role of the content block in the chat thread, e.g., user, AI, etc.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ChatRole Role { get; init; } = ChatRole.NONE;
|
public ChatRole Role { get; init; } = ChatRole.NONE;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Should the content block be hidden from the user?
|
||||||
|
/// </summary>
|
||||||
|
public bool HideFromUser { get; set; }
|
||||||
}
|
}
|
||||||
@@ -64,7 +64,7 @@ public partial class ContentBlockComponent : ComponentBase
|
|||||||
private async Task AfterStreaming()
|
private async Task AfterStreaming()
|
||||||
{
|
{
|
||||||
// Might be called from a different thread, so we need to invoke the UI thread:
|
// Might be called from a different thread, so we need to invoke the UI thread:
|
||||||
await this.InvokeAsync(() =>
|
await this.InvokeAsync(async () =>
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// Issue we try to solve: When the content changes during streaming,
|
// Issue we try to solve: When the content changes during streaming,
|
||||||
@@ -83,6 +83,9 @@ public partial class ContentBlockComponent : ComponentBase
|
|||||||
|
|
||||||
// Let Blazor update the UI, i.e., to see the render tree diff:
|
// Let Blazor update the UI, i.e., to see the render tree diff:
|
||||||
this.StateHasChanged();
|
this.StateHasChanged();
|
||||||
|
|
||||||
|
// Inform the chat that the streaming is done:
|
||||||
|
await MessageBus.INSTANCE.SendMessage<bool>(this, Event.CHAT_STREAMING_DONE);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,11 @@ public partial class Changelog
|
|||||||
|
|
||||||
public static readonly Log[] LOGS =
|
public static readonly Log[] LOGS =
|
||||||
[
|
[
|
||||||
|
new (192, "v0.9.17, build 192 (2024-11-03 11:11 UTC)", "v0.9.17.md"),
|
||||||
|
new (191, "v0.9.16, build 191 (2024-11-02 22:04 UTC)", "v0.9.16.md"),
|
||||||
|
new (190, "v0.9.15, build 190 (2024-10-28 15:04 UTC)", "v0.9.15.md"),
|
||||||
|
new (189, "v0.9.14, build 189 (2024-10-18 08:48 UTC)", "v0.9.14.md"),
|
||||||
|
new (188, "v0.9.13, build 188 (2024-10-07 11:18 UTC)", "v0.9.13.md"),
|
||||||
new (187, "v0.9.12, build 187 (2024-09-15 20:49 UTC)", "v0.9.12.md"),
|
new (187, "v0.9.12, build 187 (2024-09-15 20:49 UTC)", "v0.9.12.md"),
|
||||||
new (186, "v0.9.11, build 186 (2024-09-15 10:33 UTC)", "v0.9.11.md"),
|
new (186, "v0.9.11, build 186 (2024-09-15 10:33 UTC)", "v0.9.11.md"),
|
||||||
new (185, "v0.9.10, build 185 (2024-09-12 20:52 UTC)", "v0.9.10.md"),
|
new (185, "v0.9.10, build 185 (2024-09-12 20:52 UTC)", "v0.9.10.md"),
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
@inherits MSGComponentBase
|
@inherits MSGComponentBase
|
||||||
|
|
||||||
<div class="d-flex flex-column" style="@this.Height">
|
<div class="@this.Classes" style="@this.Styles">
|
||||||
|
@if (this.HeaderContent is not null)
|
||||||
|
{
|
||||||
|
<div>
|
||||||
|
@this.HeaderContent
|
||||||
|
</div>
|
||||||
|
}
|
||||||
<div class="flex-auto overflow-auto">
|
<div class="flex-auto overflow-auto">
|
||||||
@this.ChildContent
|
@this.ChildContent
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ namespace AIStudio.Components;
|
|||||||
|
|
||||||
public partial class InnerScrolling : MSGComponentBase
|
public partial class InnerScrolling : MSGComponentBase
|
||||||
{
|
{
|
||||||
|
[Parameter]
|
||||||
|
public bool FillEntireHorizontalSpace { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set the height of anything above the scrolling content; usually a header.
|
/// Set the height of anything above the scrolling content; usually a header.
|
||||||
/// What we do is calc(100vh - HeaderHeight). Means, you can use multiple measures like
|
/// What we do is calc(100vh - HeaderHeight). Means, you can use multiple measures like
|
||||||
@@ -14,6 +17,9 @@ public partial class InnerScrolling : MSGComponentBase
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public string HeaderHeight { get; set; } = "3em";
|
public string HeaderHeight { get; set; } = "3em";
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public RenderFragment? HeaderContent { get; set; }
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public RenderFragment? ChildContent { get; set; }
|
public RenderFragment? ChildContent { get; set; }
|
||||||
|
|
||||||
@@ -22,6 +28,9 @@ public partial class InnerScrolling : MSGComponentBase
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public RenderFragment? FooterContent { get; set; }
|
public RenderFragment? FooterContent { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string Class { get; set; } = string.Empty;
|
||||||
|
|
||||||
[CascadingParameter]
|
[CascadingParameter]
|
||||||
private MainLayout MainLayout { get; set; } = null!;
|
private MainLayout MainLayout { get; set; } = null!;
|
||||||
@@ -62,7 +71,9 @@ public partial class InnerScrolling : MSGComponentBase
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private string Height => $"height: calc(100vh - {this.HeaderHeight} - {this.MainLayout.AdditionalHeight});";
|
private string Styles => this.FillEntireHorizontalSpace ? $"height: calc(100vh - {this.HeaderHeight} - {this.MainLayout.AdditionalHeight}); overflow-x: auto; min-width: 0;" : $"height: calc(100vh - {this.HeaderHeight} - {this.MainLayout.AdditionalHeight}); flex-shrink: 0;";
|
||||||
|
|
||||||
|
private string Classes => this.FillEntireHorizontalSpace ? $"{this.Class} d-flex flex-column flex-grow-1" : $"{this.Class} d-flex flex-column";
|
||||||
|
|
||||||
public async Task ScrollToBottom()
|
public async Task ScrollToBottom()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<MudListItem T="string" Icon="@this.Icon">
|
||||||
|
@if (string.IsNullOrWhiteSpace(this.URL))
|
||||||
|
{
|
||||||
|
<MudText Typo="Typo.body1" Inline="@true">
|
||||||
|
@this.Name
|
||||||
|
</MudText>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<MudLink Href="@this.URL" Target="_blank">
|
||||||
|
@this.Name
|
||||||
|
</MudLink>
|
||||||
|
}
|
||||||
|
|
||||||
|
<MudText Typo="Typo.body1" Class="ml-3" Inline="@true">
|
||||||
|
@this.Acknowledgment
|
||||||
|
</MudText>
|
||||||
|
</MudListItem>
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
|
namespace AIStudio.Components;
|
||||||
|
|
||||||
|
public partial class Supporter : ComponentBase
|
||||||
|
{
|
||||||
|
[Parameter]
|
||||||
|
public string Name { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string Acknowledgment { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string? URL { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public SupporterType Type { get; set; }
|
||||||
|
|
||||||
|
private string Icon => this.Type switch
|
||||||
|
{
|
||||||
|
SupporterType.INDIVIDUAL => Icons.Material.Filled.Person,
|
||||||
|
SupporterType.ORGANIZATION => Icons.Material.Filled.Business,
|
||||||
|
|
||||||
|
_ => Icons.Material.Filled.Person4,
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
namespace AIStudio.Components;
|
||||||
|
|
||||||
|
public enum SupporterType
|
||||||
|
{
|
||||||
|
UNKNOWN,
|
||||||
|
INDIVIDUAL,
|
||||||
|
ORGANIZATION
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<MudTreeView T="ITreeItem" Items="@this.treeItems" SelectionMode="SelectionMode.SingleSelection" Hover="@true" ExpandOnClick="@true">
|
<MudTreeView T="ITreeItem" Items="@this.treeItems" SelectionMode="SelectionMode.SingleSelection" Hover="@true" ExpandOnClick="@true" Class="ma-3">
|
||||||
<ItemTemplate Context="item">
|
<ItemTemplate Context="item">
|
||||||
@switch (item.Value)
|
@switch (item.Value)
|
||||||
{
|
{
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
case TreeItemData treeItem:
|
case TreeItemData treeItem:
|
||||||
@if (treeItem.Type is TreeItemType.CHAT)
|
@if (treeItem.Type is TreeItemType.CHAT)
|
||||||
{
|
{
|
||||||
<MudTreeViewItem T="ITreeItem" Icon="@treeItem.Icon" Value="@item.Value" CanExpand="@treeItem.Expandable" Items="@treeItem.Children" OnClick="() => this.LoadChat(treeItem.Path, true)">
|
<MudTreeViewItem T="ITreeItem" Icon="@treeItem.Icon" Value="@item.Value" Expanded="@item.Expanded" CanExpand="@treeItem.Expandable" Items="@treeItem.Children" OnClick="() => this.LoadChat(treeItem.Path, true)">
|
||||||
<BodyContent>
|
<BodyContent>
|
||||||
<div style="display: grid; grid-template-columns: 1fr auto; align-items: center; width: 100%">
|
<div style="display: grid; grid-template-columns: 1fr auto; align-items: center; width: 100%">
|
||||||
<MudText Style="justify-self: start;">
|
<MudText Style="justify-self: start;">
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
}
|
}
|
||||||
else if (treeItem.Type is TreeItemType.WORKSPACE)
|
else if (treeItem.Type is TreeItemType.WORKSPACE)
|
||||||
{
|
{
|
||||||
<MudTreeViewItem T="ITreeItem" Icon="@treeItem.Icon" Value="@item.Value" CanExpand="@treeItem.Expandable" Items="@treeItem.Children">
|
<MudTreeViewItem T="ITreeItem" Icon="@treeItem.Icon" Value="@item.Value" Expanded="@item.Expanded" CanExpand="@treeItem.Expandable" Items="@treeItem.Children">
|
||||||
<BodyContent>
|
<BodyContent>
|
||||||
<div style="display: grid; grid-template-columns: 1fr auto; align-items: center; width: 100%">
|
<div style="display: grid; grid-template-columns: 1fr auto; align-items: center; width: 100%">
|
||||||
<MudText Style="justify-self: start;">@treeItem.Text</MudText>
|
<MudText Style="justify-self: start;">@treeItem.Text</MudText>
|
||||||
@@ -63,7 +63,7 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<MudTreeViewItem T="ITreeItem" Icon="@treeItem.Icon" Value="@item.Value" CanExpand="@treeItem.Expandable" Items="@treeItem.Children">
|
<MudTreeViewItem T="ITreeItem" Icon="@treeItem.Icon" Value="@item.Value" Expanded="@item.Expanded" CanExpand="@treeItem.Expandable" Items="@treeItem.Children">
|
||||||
<BodyContent>
|
<BodyContent>
|
||||||
<div style="display: grid; grid-template-columns: 1fr auto; align-items: center; width: 100%">
|
<div style="display: grid; grid-template-columns: 1fr auto; align-items: center; width: 100%">
|
||||||
<MudText Style="justify-self: start;">@treeItem.Text</MudText>
|
<MudText Style="justify-self: start;">@treeItem.Text</MudText>
|
||||||
|
|||||||
@@ -35,8 +35,12 @@ public partial class Workspaces : ComponentBase
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public Func<Task> LoadedChatWasChanged { get; set; } = () => Task.CompletedTask;
|
public Func<Task> LoadedChatWasChanged { get; set; } = () => Task.CompletedTask;
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public bool ExpandRootNodes { get; set; } = true;
|
||||||
|
|
||||||
private const Placement WORKSPACE_ITEM_TOOLTIP_PLACEMENT = Placement.Bottom;
|
private const Placement WORKSPACE_ITEM_TOOLTIP_PLACEMENT = Placement.Bottom;
|
||||||
|
|
||||||
|
public static readonly Guid WORKSPACE_ID_BIAS = Guid.Parse("82050a4e-ee92-43d7-8ee5-ab512f847e02");
|
||||||
private static readonly JsonSerializerOptions JSON_OPTIONS = new()
|
private static readonly JsonSerializerOptions JSON_OPTIONS = new()
|
||||||
{
|
{
|
||||||
WriteIndented = true,
|
WriteIndented = true,
|
||||||
@@ -63,6 +67,7 @@ public partial class Workspaces : ComponentBase
|
|||||||
// - When assigning the tree items to the MudTreeViewItem component, we must set the Value property to the value of the item
|
// - When assigning the tree items to the MudTreeViewItem component, we must set the Value property to the value of the item
|
||||||
//
|
//
|
||||||
|
|
||||||
|
await this.EnsureBiasWorkspace();
|
||||||
await this.LoadTreeItems();
|
await this.LoadTreeItems();
|
||||||
await base.OnInitializedAsync();
|
await base.OnInitializedAsync();
|
||||||
}
|
}
|
||||||
@@ -71,9 +76,9 @@ public partial class Workspaces : ComponentBase
|
|||||||
|
|
||||||
private async Task LoadTreeItems()
|
private async Task LoadTreeItems()
|
||||||
{
|
{
|
||||||
this.treeItems.Clear();
|
var workspacesNode = new TreeItemData<ITreeItem>
|
||||||
this.treeItems.Add(new TreeItemData<ITreeItem>
|
|
||||||
{
|
{
|
||||||
|
Expanded = this.ExpandRootNodes,
|
||||||
Expandable = true,
|
Expandable = true,
|
||||||
Value = new TreeItemData
|
Value = new TreeItemData
|
||||||
{
|
{
|
||||||
@@ -85,16 +90,11 @@ public partial class Workspaces : ComponentBase
|
|||||||
Path = "root",
|
Path = "root",
|
||||||
Children = await this.LoadWorkspaces(),
|
Children = await this.LoadWorkspaces(),
|
||||||
},
|
},
|
||||||
});
|
};
|
||||||
|
|
||||||
this.treeItems.Add(new TreeItemData<ITreeItem>
|
var tempChatNode = new TreeItemData<ITreeItem>
|
||||||
{
|
|
||||||
Expandable = false,
|
|
||||||
Value = new TreeDivider(),
|
|
||||||
});
|
|
||||||
|
|
||||||
this.treeItems.Add(new TreeItemData<ITreeItem>
|
|
||||||
{
|
{
|
||||||
|
Expanded = this.ExpandRootNodes,
|
||||||
Expandable = true,
|
Expandable = true,
|
||||||
Value = new TreeItemData
|
Value = new TreeItemData
|
||||||
{
|
{
|
||||||
@@ -106,7 +106,16 @@ public partial class Workspaces : ComponentBase
|
|||||||
Path = "temp",
|
Path = "temp",
|
||||||
Children = await this.LoadTemporaryChats(),
|
Children = await this.LoadTemporaryChats(),
|
||||||
},
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
this.treeItems.Clear();
|
||||||
|
this.treeItems.Add(workspacesNode);
|
||||||
|
this.treeItems.Add(new TreeItemData<ITreeItem>
|
||||||
|
{
|
||||||
|
Expandable = false,
|
||||||
|
Value = new TreeDivider(),
|
||||||
});
|
});
|
||||||
|
this.treeItems.Add(tempChatNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<IReadOnlyCollection<TreeItemData<ITreeItem>>> LoadTemporaryChats()
|
private async Task<IReadOnlyCollection<TreeItemData<ITreeItem>>> LoadTemporaryChats()
|
||||||
@@ -250,7 +259,7 @@ public partial class Workspaces : ComponentBase
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task StoreChat(ChatThread chat)
|
public async Task StoreChat(ChatThread chat, bool reloadTreeItems = true)
|
||||||
{
|
{
|
||||||
string chatDirectory;
|
string chatDirectory;
|
||||||
if (chat.WorkspaceId == Guid.Empty)
|
if (chat.WorkspaceId == Guid.Empty)
|
||||||
@@ -270,9 +279,29 @@ public partial class Workspaces : ComponentBase
|
|||||||
await File.WriteAllTextAsync(chatPath, JsonSerializer.Serialize(chat, JSON_OPTIONS), Encoding.UTF8);
|
await File.WriteAllTextAsync(chatPath, JsonSerializer.Serialize(chat, JSON_OPTIONS), Encoding.UTF8);
|
||||||
|
|
||||||
// Reload the tree items:
|
// Reload the tree items:
|
||||||
await this.LoadTreeItems();
|
if(reloadTreeItems)
|
||||||
|
await this.LoadTreeItems();
|
||||||
|
|
||||||
this.StateHasChanged();
|
this.StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task LoadChat(LoadChat loadChat)
|
||||||
|
{
|
||||||
|
var chatPath = loadChat.WorkspaceId == Guid.Empty
|
||||||
|
? Path.Join(SettingsManager.DataDirectory, "tempChats", loadChat.ChatId.ToString())
|
||||||
|
: Path.Join(SettingsManager.DataDirectory, "workspaces", loadChat.WorkspaceId.ToString(), loadChat.ChatId.ToString());
|
||||||
|
|
||||||
|
await this.LoadChat(chatPath, switchToChat: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsChatExisting(LoadChat loadChat)
|
||||||
|
{
|
||||||
|
var chatPath = loadChat.WorkspaceId == Guid.Empty
|
||||||
|
? Path.Join(SettingsManager.DataDirectory, "tempChats", loadChat.ChatId.ToString())
|
||||||
|
: Path.Join(SettingsManager.DataDirectory, "workspaces", loadChat.WorkspaceId.ToString(), loadChat.ChatId.ToString());
|
||||||
|
|
||||||
|
return Directory.Exists(chatPath);
|
||||||
|
}
|
||||||
|
|
||||||
private async Task<ChatThread?> LoadChat(string? chatPath, bool switchToChat)
|
private async Task<ChatThread?> LoadChat(string? chatPath, bool switchToChat)
|
||||||
{
|
{
|
||||||
@@ -434,6 +463,18 @@ public partial class Workspaces : ComponentBase
|
|||||||
|
|
||||||
await this.LoadTreeItems();
|
await this.LoadTreeItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task EnsureBiasWorkspace()
|
||||||
|
{
|
||||||
|
var workspacePath = Path.Join(SettingsManager.DataDirectory, "workspaces", WORKSPACE_ID_BIAS.ToString());
|
||||||
|
|
||||||
|
if(Path.Exists(workspacePath))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Directory.CreateDirectory(workspacePath);
|
||||||
|
var workspaceNamePath = Path.Join(workspacePath, "name");
|
||||||
|
await File.WriteAllTextAsync(workspaceNamePath, "Bias of the Day", Encoding.UTF8);
|
||||||
|
}
|
||||||
|
|
||||||
private async Task DeleteWorkspace(string? workspacePath)
|
private async Task DeleteWorkspace(string? workspacePath)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
<MudTextField
|
<MudTextField
|
||||||
T="string"
|
T="string"
|
||||||
@bind-Text="@this.dataAPIKey"
|
@bind-Text="@this.dataAPIKey"
|
||||||
Label="API Key"
|
Label="@this.APIKeyText"
|
||||||
Disabled="@(!this.NeedAPIKey)"
|
Disabled="@(!this.NeedAPIKey)"
|
||||||
Class="mb-3"
|
Class="mb-3"
|
||||||
Adornment="Adornment.Start"
|
Adornment="Adornment.Start"
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ public partial class ProviderDialog : ComponentBase
|
|||||||
//
|
//
|
||||||
// We cannot load the API key for self-hosted providers:
|
// We cannot load the API key for self-hosted providers:
|
||||||
//
|
//
|
||||||
if (this.DataLLMProvider is LLMProviders.SELF_HOSTED)
|
if (this.DataLLMProvider is LLMProviders.SELF_HOSTED && this.DataHost is not Host.OLLAMA)
|
||||||
{
|
{
|
||||||
await this.ReloadModels();
|
await this.ReloadModels();
|
||||||
await base.OnInitializedAsync();
|
await base.OnInitializedAsync();
|
||||||
@@ -149,7 +149,7 @@ public partial class ProviderDialog : ComponentBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load the API key:
|
// Load the API key:
|
||||||
var requestedSecret = await this.RustService.GetAPIKey(provider);
|
var requestedSecret = await this.RustService.GetAPIKey(provider, isTrying: this.DataLLMProvider is LLMProviders.SELF_HOSTED);
|
||||||
if(requestedSecret.Success)
|
if(requestedSecret.Success)
|
||||||
{
|
{
|
||||||
this.dataAPIKey = await requestedSecret.Secret.Decrypt(this.encryption);
|
this.dataAPIKey = await requestedSecret.Secret.Decrypt(this.encryption);
|
||||||
@@ -159,8 +159,15 @@ public partial class ProviderDialog : ComponentBase
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.dataAPIKeyStorageIssue = $"Failed to load the API key from the operating system. The message was: {requestedSecret.Issue}. You might ignore this message and provide the API key again.";
|
this.dataAPIKey = string.Empty;
|
||||||
await this.form.Validate();
|
if (this.DataLLMProvider is not LLMProviders.SELF_HOSTED)
|
||||||
|
{
|
||||||
|
this.dataAPIKeyStorageIssue = $"Failed to load the API key from the operating system. The message was: {requestedSecret.Issue}. You might ignore this message and provide the API key again.";
|
||||||
|
await this.form.Validate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// We still try to load the models. Some local hosts don't need an API key:
|
||||||
|
await this.ReloadModels();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,7 +199,7 @@ public partial class ProviderDialog : ComponentBase
|
|||||||
// Use the data model to store the provider.
|
// Use the data model to store the provider.
|
||||||
// We just return this data to the parent component:
|
// We just return this data to the parent component:
|
||||||
var addedProviderSettings = this.CreateProviderSettings();
|
var addedProviderSettings = this.CreateProviderSettings();
|
||||||
if (addedProviderSettings.UsedLLMProvider != LLMProviders.SELF_HOSTED)
|
if (!string.IsNullOrWhiteSpace(this.dataAPIKey))
|
||||||
{
|
{
|
||||||
// We need to instantiate the provider to store the API key:
|
// We need to instantiate the provider to store the API key:
|
||||||
var provider = addedProviderSettings.CreateProvider(this.Logger);
|
var provider = addedProviderSettings.CreateProvider(this.Logger);
|
||||||
@@ -363,9 +370,16 @@ public partial class ProviderDialog : ComponentBase
|
|||||||
LLMProviders.ANTHROPIC => true,
|
LLMProviders.ANTHROPIC => true,
|
||||||
|
|
||||||
LLMProviders.FIREWORKS => true,
|
LLMProviders.FIREWORKS => true,
|
||||||
|
LLMProviders.SELF_HOSTED => this.DataHost is Host.OLLAMA,
|
||||||
|
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private string APIKeyText => this.DataLLMProvider switch
|
||||||
|
{
|
||||||
|
LLMProviders.SELF_HOSTED => "(Optional) API Key",
|
||||||
|
_ => "API Key",
|
||||||
|
};
|
||||||
|
|
||||||
private bool NeedHostname => this.DataLLMProvider switch
|
private bool NeedHostname => this.DataLLMProvider switch
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
<MudMainContent Class="mud-height-full pt-1" Style="@this.PaddingLeft">
|
<MudMainContent Class="mud-height-full pt-1" Style="@this.PaddingLeft">
|
||||||
<MudContainer Fixed="@true" Class="mud-height-full" Style="margin-left: 5em; width: calc(100% - 5em);">
|
<MudContainer MaxWidth="MaxWidth.ExtraExtraLarge" Class="mud-height-full" Style="margin-left: 5em; width: calc(100% - 5em);">
|
||||||
@if (!this.performingUpdate && this.IsUpdateAlertVisible)
|
@if (!this.performingUpdate && this.IsUpdateAlertVisible)
|
||||||
{
|
{
|
||||||
<MudAlert NoIcon="@true" Severity="Severity.Info" Variant="Variant.Filled" ShowCloseIcon="@true" Dense="@true" CloseIconClicked="() => this.DismissUpdate()" Class="mt-2 mb-2">
|
<MudAlert NoIcon="@true" Severity="Severity.Info" Variant="Variant.Filled" ShowCloseIcon="@true" Dense="@true" CloseIconClicked="() => this.DismissUpdate()" Class="mt-2 mb-2">
|
||||||
|
|||||||
@@ -45,10 +45,10 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="HtmlAgilityPack" Version="1.11.65" />
|
<PackageReference Include="HtmlAgilityPack" Version="1.11.70" />
|
||||||
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="8.0.8" />
|
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="8.0.10" />
|
||||||
<PackageReference Include="MudBlazor" Version="7.8.0" />
|
<PackageReference Include="MudBlazor" Version="7.14.0" />
|
||||||
<PackageReference Include="MudBlazor.Markdown" Version="7.8.0" />
|
<PackageReference Include="MudBlazor.Markdown" Version="7.14.0" />
|
||||||
<PackageReference Include="ReverseMarkdown" Version="4.6.0" />
|
<PackageReference Include="ReverseMarkdown" Version="4.6.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,13 @@
|
|||||||
<AssistantBlock Name="Icon Finder" Description="Using a LLM to find an icon for a given context." Icon="@Icons.Material.Filled.FindInPage" Link="@Routes.ASSISTANT_ICON_FINDER"/>
|
<AssistantBlock Name="Icon Finder" Description="Using a LLM to find an icon for a given context." Icon="@Icons.Material.Filled.FindInPage" Link="@Routes.ASSISTANT_ICON_FINDER"/>
|
||||||
</MudStack>
|
</MudStack>
|
||||||
|
|
||||||
|
<MudText Typo="Typo.h4" Class="mb-2 mr-3 mt-6">
|
||||||
|
Learning
|
||||||
|
</MudText>
|
||||||
|
<MudStack Row="@true" Wrap="@Wrap.Wrap" Class="mb-3">
|
||||||
|
<AssistantBlock Name="Bias of the Day" Description="Learn about one cognitive bias every day." Icon="@Icons.Material.Filled.Psychology" Link="@Routes.ASSISTANT_BIAS"/>
|
||||||
|
</MudStack>
|
||||||
|
|
||||||
<MudText Typo="Typo.h4" Class="mb-2 mr-3 mt-6">
|
<MudText Typo="Typo.h4" Class="mb-2 mr-3 mt-6">
|
||||||
Software Engineering
|
Software Engineering
|
||||||
</MudText>
|
</MudText>
|
||||||
|
|||||||
@@ -16,79 +16,125 @@
|
|||||||
</MudText>
|
</MudText>
|
||||||
|
|
||||||
<ProviderSelection @bind-ProviderSettings="@this.providerSettings"/>
|
<ProviderSelection @bind-ProviderSettings="@this.providerSettings"/>
|
||||||
<InnerScrolling @ref="@this.scrollingArea" HeaderHeight="12.3em">
|
<MudStack Row="@true" Style="width: 100%; overflow: hidden;">
|
||||||
<ChildContent>
|
@if (this.SettingsManager.ConfigurationData.Workspace.StorageBehavior is not WorkspaceStorageBehavior.DISABLE_WORKSPACES
|
||||||
@if (this.chatThread is not null)
|
&& this.SettingsManager.ConfigurationData.Workspace.DisplayBehavior is WorkspaceDisplayBehavior.TOGGLE_SIDEBAR
|
||||||
|
&& !this.SettingsManager.ConfigurationData.Workspace.IsSidebarVisible)
|
||||||
|
{
|
||||||
|
<MudPaper Class="border border-solid rounded-lg">
|
||||||
|
<MudTooltip Text="Show your workspaces" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
|
||||||
|
<MudIconButton Size="Size.Large" Icon="@this.WorkspaceSidebarToggleIcon" OnClick="() => this.ToggleWorkspaceSidebar()"/>
|
||||||
|
</MudTooltip>
|
||||||
|
</MudPaper>
|
||||||
|
}
|
||||||
|
@if (this.SettingsManager.ConfigurationData.Workspace.StorageBehavior is not WorkspaceStorageBehavior.DISABLE_WORKSPACES)
|
||||||
|
{
|
||||||
|
@if ((this.SettingsManager.ConfigurationData.Workspace.DisplayBehavior is WorkspaceDisplayBehavior.TOGGLE_SIDEBAR && this.SettingsManager.ConfigurationData.Workspace.IsSidebarVisible) || this.SettingsManager.ConfigurationData.Workspace.DisplayBehavior is WorkspaceDisplayBehavior.SIDEBAR_ALWAYS_VISIBLE)
|
||||||
{
|
{
|
||||||
foreach (var block in this.chatThread.Blocks.OrderBy(n => n.Time))
|
@if (this.SettingsManager.ConfigurationData.Workspace.DisplayBehavior is WorkspaceDisplayBehavior.TOGGLE_SIDEBAR && this.SettingsManager.ConfigurationData.Workspace.IsSidebarVisible)
|
||||||
{
|
{
|
||||||
<ContentBlockComponent Role="@block.Role" Type="@block.ContentType" Time="@block.Time" Content="@block.Content"/>
|
<InnerScrolling HeaderHeight="12.3em" Class="border border-solid rounded-lg">
|
||||||
|
<HeaderContent>
|
||||||
|
<MudTooltip Text="Hide your workspaces" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
|
||||||
|
<MudIconButton Size="Size.Large" Icon="@this.WorkspaceSidebarToggleIcon" OnClick="() => this.ToggleWorkspaceSidebar()"/>
|
||||||
|
</MudTooltip>
|
||||||
|
</HeaderContent>
|
||||||
|
<ChildContent>
|
||||||
|
<Workspaces @ref="this.workspaces" @bind-CurrentChatThread="@this.chatThread" LoadedChatWasChanged="this.LoadedChatChanged"/>
|
||||||
|
</ChildContent>
|
||||||
|
</InnerScrolling>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<InnerScrolling HeaderHeight="12.3em" Class="border border-solid rounded-lg">
|
||||||
|
<ChildContent>
|
||||||
|
<Workspaces @ref="this.workspaces" @bind-CurrentChatThread="@this.chatThread" LoadedChatWasChanged="this.LoadedChatChanged"/>
|
||||||
|
</ChildContent>
|
||||||
|
</InnerScrolling>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</ChildContent>
|
}
|
||||||
<FooterContent>
|
<InnerScrolling FillEntireHorizontalSpace="@true" @ref="@this.scrollingArea" HeaderHeight="12.3em">
|
||||||
<MudElement Style="flex: 0 0 auto;">
|
<ChildContent>
|
||||||
<MudTextField T="string" @ref="@this.inputField" @bind-Text="@this.userInput" Variant="Variant.Outlined" AutoGrow="@true" Lines="3" MaxLines="12" Label="@this.InputLabel" Placeholder="@this.ProviderPlaceholder" Adornment="Adornment.End" AdornmentIcon="@Icons.Material.Filled.Send" OnAdornmentClick="() => this.SendMessage()" ReadOnly="!this.IsProviderSelected || this.isStreaming" Immediate="@true" OnKeyUp="this.InputKeyEvent" UserAttributes="@USER_INPUT_ATTRIBUTES" Class="@this.UserInputClass" Style="@this.UserInputStyle"/>
|
@if (this.chatThread is not null)
|
||||||
</MudElement>
|
|
||||||
<MudToolBar WrapContent="true" Gutters="@false" Class="border border-solid rounded" Style="border-color: lightgrey;">
|
|
||||||
@if (this.SettingsManager.ConfigurationData.Workspace.StorageBehavior is not WorkspaceStorageBehavior.DISABLE_WORKSPACES)
|
|
||||||
{
|
{
|
||||||
<MudTooltip Text="Your workspaces" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
|
foreach (var block in this.chatThread.Blocks.OrderBy(n => n.Time))
|
||||||
<MudIconButton Icon="@Icons.Material.Filled.SnippetFolder" OnClick="() => this.ToggleWorkspaces()"/>
|
{
|
||||||
|
@if (!block.HideFromUser)
|
||||||
|
{
|
||||||
|
<ContentBlockComponent Role="@block.Role" Type="@block.ContentType" Time="@block.Time" Content="@block.Content"/>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</ChildContent>
|
||||||
|
<FooterContent>
|
||||||
|
<MudElement Style="flex: 0 0 auto;">
|
||||||
|
<MudTextField T="string" @ref="@this.inputField" @bind-Text="@this.userInput" Variant="Variant.Outlined" AutoGrow="@true" Lines="3" MaxLines="12" Label="@this.InputLabel" Placeholder="@this.ProviderPlaceholder" Adornment="Adornment.End" AdornmentIcon="@Icons.Material.Filled.Send" OnAdornmentClick="() => this.SendMessage()" ReadOnly="!this.IsProviderSelected || this.isStreaming" Immediate="@true" OnKeyUp="this.InputKeyEvent" UserAttributes="@USER_INPUT_ATTRIBUTES" Class="@this.UserInputClass" Style="@this.UserInputStyle"/>
|
||||||
|
</MudElement>
|
||||||
|
<MudToolBar WrapContent="true" Gutters="@false" Class="border border-solid rounded" Style="border-color: lightgrey;">
|
||||||
|
@if (
|
||||||
|
this.SettingsManager.ConfigurationData.Workspace.StorageBehavior is not WorkspaceStorageBehavior.DISABLE_WORKSPACES
|
||||||
|
&& this.SettingsManager.ConfigurationData.Workspace.DisplayBehavior is WorkspaceDisplayBehavior.TOGGLE_OVERLAY)
|
||||||
|
{
|
||||||
|
<MudTooltip Text="Show your workspaces" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
|
||||||
|
<MudIconButton Icon="@Icons.Material.Filled.SnippetFolder" OnClick="() => this.ToggleWorkspaceOverlay()"/>
|
||||||
|
</MudTooltip>
|
||||||
|
}
|
||||||
|
|
||||||
|
@if (this.SettingsManager.ConfigurationData.Workspace.StorageBehavior is WorkspaceStorageBehavior.STORE_CHATS_MANUALLY)
|
||||||
|
{
|
||||||
|
<MudTooltip Text="Save chat" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
|
||||||
|
<MudIconButton Icon="@Icons.Material.Filled.Save" OnClick="() => this.SaveThread()" Disabled="@(!this.CanThreadBeSaved)"/>
|
||||||
|
</MudTooltip>
|
||||||
|
}
|
||||||
|
|
||||||
|
<MudTooltip Text="Start temporary chat" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
|
||||||
|
<MudIconButton Icon="@Icons.Material.Filled.AddComment" OnClick="() => this.StartNewChat(useSameWorkspace: false)"/>
|
||||||
</MudTooltip>
|
</MudTooltip>
|
||||||
}
|
|
||||||
|
|
||||||
@if (this.SettingsManager.ConfigurationData.Workspace.StorageBehavior is WorkspaceStorageBehavior.STORE_CHATS_MANUALLY)
|
@if (!string.IsNullOrWhiteSpace(this.currentWorkspaceName))
|
||||||
{
|
{
|
||||||
<MudTooltip Text="Save chat" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
|
<MudTooltip Text="@this.TooltipAddChatToWorkspace" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
|
||||||
<MudIconButton Icon="@Icons.Material.Filled.Save" OnClick="() => this.SaveThread()" Disabled="@(!this.CanThreadBeSaved)"/>
|
<MudIconButton Icon="@Icons.Material.Filled.CommentBank" OnClick="() => this.StartNewChat(useSameWorkspace: true)"/>
|
||||||
</MudTooltip>
|
</MudTooltip>
|
||||||
}
|
}
|
||||||
|
|
||||||
<MudTooltip Text="Start temporary chat" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
|
@if (this.SettingsManager.ConfigurationData.Workspace.StorageBehavior is WorkspaceStorageBehavior.STORE_CHATS_AUTOMATICALLY)
|
||||||
<MudIconButton Icon="@Icons.Material.Filled.AddComment" OnClick="() => this.StartNewChat(useSameWorkspace: false)"/>
|
{
|
||||||
</MudTooltip>
|
<MudTooltip Text="Delete this chat & start a new one" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
|
||||||
|
<MudIconButton Icon="@Icons.Material.Filled.Refresh" OnClick="() => this.StartNewChat(useSameWorkspace: true, deletePreviousChat: true)" Disabled="@(!this.CanThreadBeSaved)"/>
|
||||||
|
</MudTooltip>
|
||||||
|
}
|
||||||
|
|
||||||
@if (!string.IsNullOrWhiteSpace(this.currentWorkspaceName))
|
@if (this.SettingsManager.ConfigurationData.Workspace.StorageBehavior is not WorkspaceStorageBehavior.DISABLE_WORKSPACES)
|
||||||
{
|
{
|
||||||
<MudTooltip Text="@this.TooltipAddChatToWorkspace" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
|
<MudTooltip Text="Move the chat to a workspace, or to another if it is already in one." Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
|
||||||
<MudIconButton Icon="@Icons.Material.Filled.CommentBank" OnClick="() => this.StartNewChat(useSameWorkspace: true)"/>
|
<MudIconButton Icon="@Icons.Material.Filled.MoveToInbox" Disabled="@(!this.CanThreadBeSaved)" OnClick="() => this.MoveChatToWorkspace()"/>
|
||||||
</MudTooltip>
|
</MudTooltip>
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (this.SettingsManager.ConfigurationData.Workspace.StorageBehavior is WorkspaceStorageBehavior.STORE_CHATS_AUTOMATICALLY)
|
|
||||||
{
|
|
||||||
<MudTooltip Text="Delete this chat & start a new one" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
|
|
||||||
<MudIconButton Icon="@Icons.Material.Filled.Refresh" OnClick="() => this.StartNewChat(useSameWorkspace: true, deletePreviousChat: true)" Disabled="@(!this.CanThreadBeSaved)"/>
|
|
||||||
</MudTooltip>
|
|
||||||
}
|
|
||||||
|
|
||||||
@if (this.SettingsManager.ConfigurationData.Workspace.StorageBehavior is not WorkspaceStorageBehavior.DISABLE_WORKSPACES)
|
@if (this.SettingsManager.ConfigurationData.LLMProviders.ShowProviderConfidence)
|
||||||
{
|
{
|
||||||
<MudTooltip Text="Move the chat to a workspace, or to another if it is already in one." Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
|
<ConfidenceInfo Mode="ConfidenceInfoMode.ICON" LLMProvider="@this.providerSettings.UsedLLMProvider"/>
|
||||||
<MudIconButton Icon="@Icons.Material.Filled.MoveToInbox" Disabled="@(!this.CanThreadBeSaved)" OnClick="() => this.MoveChatToWorkspace()"/>
|
}
|
||||||
</MudTooltip>
|
|
||||||
}
|
|
||||||
|
|
||||||
@if (this.SettingsManager.ConfigurationData.LLMProviders.ShowProviderConfidence)
|
<ProfileSelection CurrentProfile="@this.currentProfile" CurrentProfileChanged="@this.ProfileWasChanged" />
|
||||||
{
|
</MudToolBar>
|
||||||
<ConfidenceInfo Mode="ConfidenceInfoMode.ICON" LLMProvider="@this.providerSettings.UsedLLMProvider"/>
|
</FooterContent>
|
||||||
}
|
</InnerScrolling>
|
||||||
|
</MudStack>
|
||||||
|
|
||||||
<ProfileSelection CurrentProfile="@this.currentProfile" CurrentProfileChanged="@this.ProfileWasChanged" />
|
@if (
|
||||||
</MudToolBar>
|
this.SettingsManager.ConfigurationData.Workspace.StorageBehavior != WorkspaceStorageBehavior.DISABLE_WORKSPACES
|
||||||
</FooterContent>
|
&& this.SettingsManager.ConfigurationData.Workspace.DisplayBehavior is WorkspaceDisplayBehavior.TOGGLE_OVERLAY)
|
||||||
</InnerScrolling>
|
|
||||||
|
|
||||||
@if (this.SettingsManager.ConfigurationData.Workspace.StorageBehavior != WorkspaceStorageBehavior.DISABLE_WORKSPACES)
|
|
||||||
{
|
{
|
||||||
<MudDrawer @bind-Open="@this.workspacesVisible" Width="40em" Height="100%" Anchor="Anchor.Start" Variant="DrawerVariant.Temporary" Elevation="1">
|
<MudDrawer @bind-Open="@this.workspaceOverlayVisible" Width="40em" Height="100%" Anchor="Anchor.Start" Variant="DrawerVariant.Temporary" Elevation="1">
|
||||||
<MudDrawerHeader>
|
<MudDrawerHeader>
|
||||||
<MudStack Row="@true" AlignItems="AlignItems.Center">
|
<MudStack Row="@true" AlignItems="AlignItems.Center">
|
||||||
<MudText Typo="Typo.h6" Class="mr-3">
|
<MudText Typo="Typo.h6" Class="mr-3">
|
||||||
Your workspaces
|
Your workspaces
|
||||||
</MudText>
|
</MudText>
|
||||||
<MudIconButton Icon="@Icons.Material.Filled.Close" Variant="Variant.Filled" Color="Color.Default" Size="Size.Small" OnClick="() => this.ToggleWorkspaces()"/>
|
<MudIconButton Icon="@Icons.Material.Filled.Close" Variant="Variant.Filled" Color="Color.Default" Size="Size.Small" OnClick="() => this.ToggleWorkspaceOverlay()"/>
|
||||||
</MudStack>
|
</MudStack>
|
||||||
</MudDrawerHeader>
|
</MudDrawerHeader>
|
||||||
<MudDrawerContainer Class="ml-6">
|
<MudDrawerContainer Class="ml-6">
|
||||||
|
|||||||
@@ -42,10 +42,14 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable
|
|||||||
private string userInput = string.Empty;
|
private string userInput = string.Empty;
|
||||||
private string currentWorkspaceName = string.Empty;
|
private string currentWorkspaceName = string.Empty;
|
||||||
private Guid currentWorkspaceId = Guid.Empty;
|
private Guid currentWorkspaceId = Guid.Empty;
|
||||||
private bool workspacesVisible;
|
private bool workspaceOverlayVisible;
|
||||||
private Workspaces? workspaces;
|
private Workspaces? workspaces;
|
||||||
private bool mustScrollToBottomAfterRender;
|
private bool mustScrollToBottomAfterRender;
|
||||||
|
private bool mustStoreChat;
|
||||||
|
private bool mustLoadChat;
|
||||||
|
private LoadChat loadChat;
|
||||||
private byte scrollRenderCountdown;
|
private byte scrollRenderCountdown;
|
||||||
|
private bool autoSaveEnabled;
|
||||||
|
|
||||||
// Unfortunately, we need the input field reference to blur the focus away. Without
|
// Unfortunately, we need the input field reference to blur the focus away. Without
|
||||||
// this, we cannot clear the input field.
|
// this, we cannot clear the input field.
|
||||||
@@ -55,7 +59,7 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable
|
|||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
this.ApplyFilters([], [ Event.HAS_CHAT_UNSAVED_CHANGES, Event.RESET_CHAT_STATE ]);
|
this.ApplyFilters([], [ Event.HAS_CHAT_UNSAVED_CHANGES, Event.RESET_CHAT_STATE, Event.CHAT_STREAMING_DONE ]);
|
||||||
|
|
||||||
// Configure the spellchecking for the user input:
|
// Configure the spellchecking for the user input:
|
||||||
this.SettingsManager.InjectSpellchecking(USER_INPUT_ATTRIBUTES);
|
this.SettingsManager.InjectSpellchecking(USER_INPUT_ATTRIBUTES);
|
||||||
@@ -68,14 +72,23 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable
|
|||||||
this.chatThread = deferredContent;
|
this.chatThread = deferredContent;
|
||||||
if (this.chatThread is not null)
|
if (this.chatThread is not null)
|
||||||
{
|
{
|
||||||
var firstUserBlock = this.chatThread.Blocks.FirstOrDefault(x => x.Role == ChatRole.USER);
|
if (string.IsNullOrWhiteSpace(this.chatThread.Name))
|
||||||
if (firstUserBlock is not null)
|
|
||||||
{
|
{
|
||||||
this.chatThread.Name = firstUserBlock.Content switch
|
var firstUserBlock = this.chatThread.Blocks.FirstOrDefault(x => x.Role == ChatRole.USER);
|
||||||
|
if (firstUserBlock is not null)
|
||||||
{
|
{
|
||||||
ContentText textBlock => this.ExtractThreadName(textBlock.Text),
|
this.chatThread.Name = firstUserBlock.Content switch
|
||||||
_ => "Thread"
|
{
|
||||||
};
|
ContentText textBlock => this.ExtractThreadName(textBlock.Text),
|
||||||
|
_ => "Thread"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.chatThread.WorkspaceId != Guid.Empty)
|
||||||
|
{
|
||||||
|
this.autoSaveEnabled = true;
|
||||||
|
this.mustStoreChat = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,12 +99,33 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable
|
|||||||
this.StateHasChanged();
|
this.StateHasChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var deferredLoading = MessageBus.INSTANCE.CheckDeferredMessages<LoadChat>(Event.LOAD_CHAT).FirstOrDefault();
|
||||||
|
if (deferredLoading != default)
|
||||||
|
{
|
||||||
|
this.loadChat = deferredLoading;
|
||||||
|
this.mustLoadChat = true;
|
||||||
|
}
|
||||||
|
|
||||||
await base.OnInitializedAsync();
|
await base.OnInitializedAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||||
{
|
{
|
||||||
|
if (firstRender && this.workspaces is not null && this.chatThread is not null && this.mustStoreChat)
|
||||||
|
{
|
||||||
|
this.mustStoreChat = false;
|
||||||
|
await this.workspaces.StoreChat(this.chatThread, false);
|
||||||
|
this.currentWorkspaceId = this.chatThread.WorkspaceId;
|
||||||
|
this.currentWorkspaceName = await this.workspaces.LoadWorkspaceName(this.chatThread.WorkspaceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (firstRender && this.workspaces is not null && this.mustLoadChat)
|
||||||
|
{
|
||||||
|
this.mustLoadChat = false;
|
||||||
|
await this.workspaces.LoadChat(this.loadChat);
|
||||||
|
}
|
||||||
|
|
||||||
if(this.mustScrollToBottomAfterRender)
|
if(this.mustScrollToBottomAfterRender)
|
||||||
{
|
{
|
||||||
if (--this.scrollRenderCountdown == 0)
|
if (--this.scrollRenderCountdown == 0)
|
||||||
@@ -123,6 +157,8 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable
|
|||||||
private string UserInputStyle => this.SettingsManager.ConfigurationData.LLMProviders.ShowProviderConfidence ? this.providerSettings.UsedLLMProvider.GetConfidence(this.SettingsManager).SetColorStyle(this.SettingsManager) : string.Empty;
|
private string UserInputStyle => this.SettingsManager.ConfigurationData.LLMProviders.ShowProviderConfidence ? this.providerSettings.UsedLLMProvider.GetConfidence(this.SettingsManager).SetColorStyle(this.SettingsManager) : string.Empty;
|
||||||
|
|
||||||
private string UserInputClass => this.SettingsManager.ConfigurationData.LLMProviders.ShowProviderConfidence ? "confidence-border" : string.Empty;
|
private string UserInputClass => this.SettingsManager.ConfigurationData.LLMProviders.ShowProviderConfidence ? "confidence-border" : string.Empty;
|
||||||
|
|
||||||
|
private string WorkspaceSidebarToggleIcon => this.SettingsManager.ConfigurationData.Workspace.IsSidebarVisible ? Icons.Material.Filled.ArrowCircleLeft : Icons.Material.Filled.ArrowCircleRight;
|
||||||
|
|
||||||
private void ProfileWasChanged(Profile profile)
|
private void ProfileWasChanged(Profile profile)
|
||||||
{
|
{
|
||||||
@@ -274,9 +310,15 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ToggleWorkspaces()
|
private void ToggleWorkspaceOverlay()
|
||||||
{
|
{
|
||||||
this.workspacesVisible = !this.workspacesVisible;
|
this.workspaceOverlayVisible = !this.workspaceOverlayVisible;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ToggleWorkspaceSidebar()
|
||||||
|
{
|
||||||
|
this.SettingsManager.ConfigurationData.Workspace.IsSidebarVisible = !this.SettingsManager.ConfigurationData.Workspace.IsSidebarVisible;
|
||||||
|
await this.SettingsManager.StoreSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SaveThread()
|
private async Task SaveThread()
|
||||||
@@ -455,16 +497,19 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable
|
|||||||
|
|
||||||
#region Overrides of MSGComponentBase
|
#region Overrides of MSGComponentBase
|
||||||
|
|
||||||
public override Task ProcessIncomingMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data) where T : default
|
public override async Task ProcessIncomingMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data) where T : default
|
||||||
{
|
{
|
||||||
switch (triggeredEvent)
|
switch (triggeredEvent)
|
||||||
{
|
{
|
||||||
case Event.RESET_CHAT_STATE:
|
case Event.RESET_CHAT_STATE:
|
||||||
this.ResetState();
|
this.ResetState();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Event.CHAT_STREAMING_DONE:
|
||||||
|
if(this.autoSaveEnabled)
|
||||||
|
await this.SaveThread();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task<TResult?> ProcessMessageWithResult<TPayload, TResult>(ComponentBase? sendingComponent, Event triggeredEvent, TPayload? data) where TResult : default where TPayload : default
|
public override Task<TResult?> ProcessMessageWithResult<TPayload, TResult>(ComponentBase? sendingComponent, Event triggeredEvent, TPayload? data) where TResult : default where TPayload : default
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
@using AIStudio.Assistants.TextSummarizer
|
@using AIStudio.Assistants.TextSummarizer
|
||||||
@using AIStudio.Provider
|
@using AIStudio.Provider
|
||||||
@using AIStudio.Settings
|
@using AIStudio.Settings
|
||||||
|
@using AIStudio.Settings.DataModel
|
||||||
@using Host = AIStudio.Provider.SelfHosted.Host
|
@using Host = AIStudio.Provider.SelfHosted.Host
|
||||||
|
|
||||||
<MudText Typo="Typo.h3" Class="mb-12">Settings</MudText>
|
<MudText Typo="Typo.h3" Class="mb-12">Settings</MudText>
|
||||||
@@ -201,7 +202,12 @@
|
|||||||
|
|
||||||
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.Work" HeaderText="Workspace Options">
|
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.Work" HeaderText="Workspace Options">
|
||||||
<ConfigurationSelect OptionDescription="Workspace behavior" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Workspace.StorageBehavior)" Data="@ConfigurationSelectDataFactory.GetWorkspaceStorageBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Workspace.StorageBehavior = selectedValue)" OptionHelp="Should we store your chats?"/>
|
<ConfigurationSelect OptionDescription="Workspace behavior" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Workspace.StorageBehavior)" Data="@ConfigurationSelectDataFactory.GetWorkspaceStorageBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Workspace.StorageBehavior = selectedValue)" OptionHelp="Should we store your chats?"/>
|
||||||
<ConfigurationSelect OptionDescription="Workspace maintenance" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Workspace.StorageTemporaryMaintenancePolicy)" Data="@ConfigurationSelectDataFactory.GetWorkspaceStorageTemporaryMaintenancePolicyData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Workspace.StorageTemporaryMaintenancePolicy = selectedValue)" OptionHelp="If and when should we delete your temporary chats?"/>
|
|
||||||
|
@if (this.SettingsManager.ConfigurationData.Workspace.StorageBehavior is not WorkspaceStorageBehavior.DISABLE_WORKSPACES)
|
||||||
|
{
|
||||||
|
<ConfigurationSelect OptionDescription="Workspace maintenance" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Workspace.StorageTemporaryMaintenancePolicy)" Data="@ConfigurationSelectDataFactory.GetWorkspaceStorageTemporaryMaintenancePolicyData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Workspace.StorageTemporaryMaintenancePolicy = selectedValue)" OptionHelp="If and when should we delete your temporary chats?"/>
|
||||||
|
<ConfigurationSelect OptionDescription="Workspace display behavior" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Workspace.DisplayBehavior)" Data="@ConfigurationSelectDataFactory.GetWorkspaceDisplayBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Workspace.DisplayBehavior = selectedValue)" OptionHelp="How should we display your workspaces?"/>
|
||||||
|
}
|
||||||
</ExpansionPanel>
|
</ExpansionPanel>
|
||||||
|
|
||||||
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.FindInPage" HeaderText="Assistant: Icon Finder Options">
|
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.FindInPage" HeaderText="Assistant: Icon Finder Options">
|
||||||
@@ -400,6 +406,32 @@
|
|||||||
<ConfigurationProviderSelection Component="Components.MY_TASKS_ASSISTANT" Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.MyTasks.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.MyTasks.PreselectedProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.MyTasks.PreselectedProvider = selectedValue)"/>
|
<ConfigurationProviderSelection Component="Components.MY_TASKS_ASSISTANT" Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.MyTasks.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.MyTasks.PreselectedProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.MyTasks.PreselectedProvider = selectedValue)"/>
|
||||||
</MudPaper>
|
</MudPaper>
|
||||||
</ExpansionPanel>
|
</ExpansionPanel>
|
||||||
|
|
||||||
|
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.Psychology" HeaderText="Assistant: Bias of the Day">
|
||||||
|
|
||||||
|
<ConfigurationOption OptionDescription="Restrict to one bias a day?" LabelOn="Yes, you can only retrieve one bias per day" LabelOff="No restriction. You can retrieve as many biases as you want per day." State="@(() => this.SettingsManager.ConfigurationData.BiasOfTheDay.RestrictOneBiasPerDay)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.BiasOfTheDay.RestrictOneBiasPerDay = updatedState)"/>
|
||||||
|
|
||||||
|
<MudField Label="Statistics" Variant="Variant.Outlined" Class="mb-2">
|
||||||
|
<MudText Typo="Typo.body1">
|
||||||
|
You have learned about @this.SettingsManager.ConfigurationData.BiasOfTheDay.UsedBias.Count out of @BiasCatalog.ALL_BIAS.Count biases.
|
||||||
|
</MudText>
|
||||||
|
<MudButton Size="Size.Small" Variant="Variant.Filled" StartIcon="@Icons.Material.Filled.Restore" Color="Color.Error" OnClick="@(() => this.ResetBiasOfTheDayHistory())">
|
||||||
|
Reset
|
||||||
|
</MudButton>
|
||||||
|
</MudField>
|
||||||
|
|
||||||
|
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
|
||||||
|
<ConfigurationOption OptionDescription="Preselect options?" LabelOn="Options are preselected" LabelOff="No options are preselected" State="@(() => this.SettingsManager.ConfigurationData.BiasOfTheDay.PreselectOptions)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.BiasOfTheDay.PreselectOptions = updatedState)" OptionHelp="When enabled, you can preselect options. This is might be useful when you prefer a specific language or LLM model."/>
|
||||||
|
<ConfigurationSelect OptionDescription="Preselect the language" Disabled="@(() => !this.SettingsManager.ConfigurationData.BiasOfTheDay.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.BiasOfTheDay.PreselectedTargetLanguage)" Data="@ConfigurationSelectDataFactory.GetCommonLanguagesOptionalData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.BiasOfTheDay.PreselectedTargetLanguage = selectedValue)" OptionHelp="Which language should be preselected?"/>
|
||||||
|
@if (this.SettingsManager.ConfigurationData.BiasOfTheDay.PreselectedTargetLanguage is CommonLanguages.OTHER)
|
||||||
|
{
|
||||||
|
<ConfigurationText OptionDescription="Preselect another language" Disabled="@(() => !this.SettingsManager.ConfigurationData.BiasOfTheDay.PreselectOptions)" Icon="@Icons.Material.Filled.Translate" Text="@(() => this.SettingsManager.ConfigurationData.BiasOfTheDay.PreselectedOtherLanguage)" TextUpdate="@(updatedText => this.SettingsManager.ConfigurationData.BiasOfTheDay.PreselectedOtherLanguage = updatedText)"/>
|
||||||
|
}
|
||||||
|
<ConfigurationSelect OptionDescription="Preselect one of your profiles?" Disabled="@(() => !this.SettingsManager.ConfigurationData.BiasOfTheDay.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.BiasOfTheDay.PreselectedProfile)" Data="@ConfigurationSelectDataFactory.GetProfilesData(this.SettingsManager.ConfigurationData.Profiles)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.BiasOfTheDay.PreselectedProfile = selectedValue)" OptionHelp="Would you like to preselect one of your profiles?"/>
|
||||||
|
<ConfigurationMinConfidenceSelection Disabled="@(() => !this.SettingsManager.ConfigurationData.BiasOfTheDay.PreselectOptions)" RestrictToGlobalMinimumConfidence="@true" SelectedValue="@(() => this.SettingsManager.ConfigurationData.BiasOfTheDay.MinimumProviderConfidence)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.BiasOfTheDay.MinimumProviderConfidence = selectedValue)"/>
|
||||||
|
<ConfigurationProviderSelection Component="Components.BIAS_DAY_ASSISTANT" Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.BiasOfTheDay.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.BiasOfTheDay.PreselectedProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.BiasOfTheDay.PreselectedProvider = selectedValue)"/>
|
||||||
|
</MudPaper>
|
||||||
|
</ExpansionPanel>
|
||||||
|
|
||||||
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.TextFields" HeaderText="Agent: Text Content Cleaner Options">
|
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.TextFields" HeaderText="Agent: Text Content Cleaner Options">
|
||||||
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
|
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
|
||||||
|
|||||||
@@ -249,6 +249,29 @@ public partial class Settings : ComponentBase, IMessageBusReceiver, IDisposable
|
|||||||
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
|
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Bias-of-the-day related
|
||||||
|
|
||||||
|
private async Task ResetBiasOfTheDayHistory()
|
||||||
|
{
|
||||||
|
var dialogParameters = new DialogParameters
|
||||||
|
{
|
||||||
|
{ "Message", "Are you sure you want to reset your bias-of-the-day statistics? The system will no longer remember which biases you already know. As a result, biases you are already familiar with may be addressed again." },
|
||||||
|
};
|
||||||
|
|
||||||
|
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>("Reset your bias-of-the-day statistics", dialogParameters, DialogOptions.FULLSCREEN);
|
||||||
|
var dialogResult = await dialogReference.Result;
|
||||||
|
if (dialogResult is null || dialogResult.Canceled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.SettingsManager.ConfigurationData.BiasOfTheDay.UsedBias.Clear();
|
||||||
|
this.SettingsManager.ConfigurationData.BiasOfTheDay.DateLastBiasDrawn = DateOnly.MinValue;
|
||||||
|
await this.SettingsManager.StoreSettings();
|
||||||
|
|
||||||
|
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Implementation of IMessageBusReceiver
|
#region Implementation of IMessageBusReceiver
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
</MudButton>
|
</MudButton>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<MudGrid Justify="Justify.Center" Spacing="2" Style="width: 100%;" Class="align-center ma-0">
|
<MudGrid Justify="Justify.Center" Spacing="2" Style="width: 100%;" Class="ma-0">
|
||||||
<MudItem Class="pa-0 pr-2" xs="6">
|
<MudItem Class="pa-0 pr-2" xs="6">
|
||||||
<MudPaper Elevation="3" Class="border-solid border rounded-lg pa-3">
|
<MudPaper Elevation="3" Class="border-solid border rounded-lg pa-3">
|
||||||
<MudText Typo="Typo.h4" Class="mb-3 d-flex align-center">
|
<MudText Typo="Typo.h4" Class="mb-3 d-flex align-center">
|
||||||
@@ -28,6 +28,14 @@
|
|||||||
<MudButton Href="https://github.com/sponsors/MindWorkAI" StartIcon="@Icons.Material.Filled.People" Variant="Variant.Filled" Target="_blank">
|
<MudButton Href="https://github.com/sponsors/MindWorkAI" StartIcon="@Icons.Material.Filled.People" Variant="Variant.Filled" Target="_blank">
|
||||||
Become a contributor
|
Become a contributor
|
||||||
</MudButton>
|
</MudButton>
|
||||||
|
|
||||||
|
<MudText Typo="Typo.h6" Class="mt-8">
|
||||||
|
The first 10 supporters who make a monthly contribution:
|
||||||
|
</MudText>
|
||||||
|
<MudList T="string">
|
||||||
|
<Supporter Name="richard-stanton" Type="SupporterType.INDIVIDUAL" URL="https://github.com/richard-stanton" Acknowledgment="Thank you, Richard, for being the first."/>
|
||||||
|
<Supporter Name="peerschuett" Type="SupporterType.INDIVIDUAL" URL="https://github.com/peerschuett" Acknowledgment="Thank you, Peer, for your courage in being the second person to support the project financially."/>
|
||||||
|
</MudList>
|
||||||
</MudPaper>
|
</MudPaper>
|
||||||
</MudItem>
|
</MudItem>
|
||||||
|
|
||||||
|
|||||||
@@ -147,8 +147,13 @@ public sealed class ProviderAnthropic(ILogger logger) : BaseProvider("https://ap
|
|||||||
{
|
{
|
||||||
return Task.FromResult(new[]
|
return Task.FromResult(new[]
|
||||||
{
|
{
|
||||||
|
new Model("claude-3-5-sonnet-latest"),
|
||||||
new Model("claude-3-5-sonnet-20240620"),
|
new Model("claude-3-5-sonnet-20240620"),
|
||||||
|
new Model("claude-3-5-sonnet-20241022"),
|
||||||
|
|
||||||
new Model("claude-3-opus-20240229"),
|
new Model("claude-3-opus-20240229"),
|
||||||
|
new Model("claude-3-opus-latest"),
|
||||||
|
|
||||||
new Model("claude-3-sonnet-20240229"),
|
new Model("claude-3-sonnet-20240229"),
|
||||||
new Model("claude-3-haiku-20240307"),
|
new Model("claude-3-haiku-20240307"),
|
||||||
}.AsEnumerable());
|
}.AsEnumerable());
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using System.Net.Http.Headers;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
@@ -23,6 +24,9 @@ public sealed class ProviderSelfHosted(ILogger logger, Settings.Provider provide
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public async IAsyncEnumerable<string> StreamChatCompletion(Provider.Model chatModel, ChatThread chatThread, [EnumeratorCancellation] CancellationToken token = default)
|
public async IAsyncEnumerable<string> StreamChatCompletion(Provider.Model chatModel, ChatThread chatThread, [EnumeratorCancellation] CancellationToken token = default)
|
||||||
{
|
{
|
||||||
|
// Get the API key:
|
||||||
|
var requestedSecret = await RUST_SERVICE.GetAPIKey(this, isTrying: true);
|
||||||
|
|
||||||
// Prepare the system prompt:
|
// Prepare the system prompt:
|
||||||
var systemPrompt = new Message
|
var systemPrompt = new Message
|
||||||
{
|
{
|
||||||
@@ -62,68 +66,83 @@ public sealed class ProviderSelfHosted(ILogger logger, Settings.Provider provide
|
|||||||
MaxTokens = -1,
|
MaxTokens = -1,
|
||||||
}, JSON_SERIALIZER_OPTIONS);
|
}, JSON_SERIALIZER_OPTIONS);
|
||||||
|
|
||||||
// Build the HTTP post request:
|
StreamReader? streamReader = default;
|
||||||
var request = new HttpRequestMessage(HttpMethod.Post, provider.Host.ChatURL());
|
try
|
||||||
|
|
||||||
// Set the content:
|
|
||||||
request.Content = new StringContent(providerChatRequest, Encoding.UTF8, "application/json");
|
|
||||||
|
|
||||||
// Send the request with the ResponseHeadersRead option.
|
|
||||||
// This allows us to read the stream as soon as the headers are received.
|
|
||||||
// This is important because we want to stream the responses.
|
|
||||||
var response = await this.httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, token);
|
|
||||||
|
|
||||||
// Open the response stream:
|
|
||||||
var providerStream = await response.Content.ReadAsStreamAsync(token);
|
|
||||||
|
|
||||||
// Add a stream reader to read the stream, line by line:
|
|
||||||
var streamReader = new StreamReader(providerStream);
|
|
||||||
|
|
||||||
// Read the stream, line by line:
|
|
||||||
while(!streamReader.EndOfStream)
|
|
||||||
{
|
{
|
||||||
// Check if the token is canceled:
|
// Build the HTTP post request:
|
||||||
if(token.IsCancellationRequested)
|
var request = new HttpRequestMessage(HttpMethod.Post, provider.Host.ChatURL());
|
||||||
yield break;
|
|
||||||
|
|
||||||
// Read the next line:
|
|
||||||
var line = await streamReader.ReadLineAsync(token);
|
|
||||||
|
|
||||||
// Skip empty lines:
|
|
||||||
if(string.IsNullOrWhiteSpace(line))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Skip lines that do not start with "data: ". Regard
|
|
||||||
// to the specification, we only want to read the data lines:
|
|
||||||
if(!line.StartsWith("data: ", StringComparison.InvariantCulture))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Check if the line is the end of the stream:
|
// Set the authorization header:
|
||||||
if (line.StartsWith("data: [DONE]", StringComparison.InvariantCulture))
|
if (requestedSecret.Success)
|
||||||
yield break;
|
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", await requestedSecret.Secret.Decrypt(ENCRYPTION));
|
||||||
|
|
||||||
ResponseStreamLine providerResponse;
|
// Set the content:
|
||||||
try
|
request.Content = new StringContent(providerChatRequest, Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
|
// Send the request with the ResponseHeadersRead option.
|
||||||
|
// This allows us to read the stream as soon as the headers are received.
|
||||||
|
// This is important because we want to stream the responses.
|
||||||
|
var response = await this.httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, token);
|
||||||
|
|
||||||
|
// Open the response stream:
|
||||||
|
var providerStream = await response.Content.ReadAsStreamAsync(token);
|
||||||
|
|
||||||
|
// Add a stream reader to read the stream, line by line:
|
||||||
|
streamReader = new StreamReader(providerStream);
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
this.logger.LogError($"Failed to stream chat completion from self-hosted provider '{this.InstanceName}': {e.Message}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (streamReader is not null)
|
||||||
|
{
|
||||||
|
// Read the stream, line by line:
|
||||||
|
while (!streamReader.EndOfStream)
|
||||||
{
|
{
|
||||||
// We know that the line starts with "data: ". Hence, we can
|
// Check if the token is canceled:
|
||||||
// skip the first 6 characters to get the JSON data after that.
|
if (token.IsCancellationRequested)
|
||||||
var jsonData = line[6..];
|
yield break;
|
||||||
|
|
||||||
// Deserialize the JSON data:
|
// Read the next line:
|
||||||
providerResponse = JsonSerializer.Deserialize<ResponseStreamLine>(jsonData, JSON_SERIALIZER_OPTIONS);
|
var line = await streamReader.ReadLineAsync(token);
|
||||||
|
|
||||||
|
// Skip empty lines:
|
||||||
|
if (string.IsNullOrWhiteSpace(line))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Skip lines that do not start with "data: ". Regard
|
||||||
|
// to the specification, we only want to read the data lines:
|
||||||
|
if (!line.StartsWith("data: ", StringComparison.InvariantCulture))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Check if the line is the end of the stream:
|
||||||
|
if (line.StartsWith("data: [DONE]", StringComparison.InvariantCulture))
|
||||||
|
yield break;
|
||||||
|
|
||||||
|
ResponseStreamLine providerResponse;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// We know that the line starts with "data: ". Hence, we can
|
||||||
|
// skip the first 6 characters to get the JSON data after that.
|
||||||
|
var jsonData = line[6..];
|
||||||
|
|
||||||
|
// Deserialize the JSON data:
|
||||||
|
providerResponse = JsonSerializer.Deserialize<ResponseStreamLine>(jsonData, JSON_SERIALIZER_OPTIONS);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// Skip invalid JSON data:
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip empty responses:
|
||||||
|
if (providerResponse == default || providerResponse.Choices.Count == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Yield the response:
|
||||||
|
yield return providerResponse.Choices[0].Delta.Content;
|
||||||
}
|
}
|
||||||
catch
|
|
||||||
{
|
|
||||||
// Skip invalid JSON data:
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skip empty responses:
|
|
||||||
if(providerResponse == default || providerResponse.Choices.Count == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Yield the response:
|
|
||||||
yield return providerResponse.Choices[0].Delta.Content;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,7 +168,21 @@ public sealed class ProviderSelfHosted(ILogger logger, Settings.Provider provide
|
|||||||
|
|
||||||
case Host.LM_STUDIO:
|
case Host.LM_STUDIO:
|
||||||
case Host.OLLAMA:
|
case Host.OLLAMA:
|
||||||
|
|
||||||
|
var secretKey = apiKeyProvisional switch
|
||||||
|
{
|
||||||
|
not null => apiKeyProvisional,
|
||||||
|
_ => await RUST_SERVICE.GetAPIKey(this, isTrying: true) switch
|
||||||
|
{
|
||||||
|
{ Success: true } result => await result.Secret.Decrypt(ENCRYPTION),
|
||||||
|
_ => null,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var lmStudioRequest = new HttpRequestMessage(HttpMethod.Get, "models");
|
var lmStudioRequest = new HttpRequestMessage(HttpMethod.Get, "models");
|
||||||
|
if(secretKey is not null)
|
||||||
|
lmStudioRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", apiKeyProvisional);
|
||||||
|
|
||||||
var lmStudioResponse = await this.httpClient.SendAsync(lmStudioRequest, token);
|
var lmStudioResponse = await this.httpClient.SendAsync(lmStudioRequest, token);
|
||||||
if(!lmStudioResponse.IsSuccessStatusCode)
|
if(!lmStudioResponse.IsSuccessStatusCode)
|
||||||
return [];
|
return [];
|
||||||
|
|||||||
@@ -22,5 +22,6 @@ public sealed partial class Routes
|
|||||||
public const string ASSISTANT_SYNONYMS = "/assistant/synonyms";
|
public const string ASSISTANT_SYNONYMS = "/assistant/synonyms";
|
||||||
public const string ASSISTANT_MY_TASKS = "/assistant/my-tasks";
|
public const string ASSISTANT_MY_TASKS = "/assistant/my-tasks";
|
||||||
public const string ASSISTANT_JOB_POSTING = "/assistant/job-posting";
|
public const string ASSISTANT_JOB_POSTING = "/assistant/job-posting";
|
||||||
|
public const string ASSISTANT_BIAS = "/assistant/bias-of-the-day";
|
||||||
// ReSharper restore InconsistentNaming
|
// ReSharper restore InconsistentNaming
|
||||||
}
|
}
|
||||||
@@ -58,6 +58,13 @@ public static class ConfigurationSelectDataFactory
|
|||||||
yield return new("Delete temporary chats older than 1 year", WorkspaceStorageTemporaryMaintenancePolicy.DELETE_OLDER_THAN_365_DAYS);
|
yield return new("Delete temporary chats older than 1 year", WorkspaceStorageTemporaryMaintenancePolicy.DELETE_OLDER_THAN_365_DAYS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<ConfigurationSelectData<WorkspaceDisplayBehavior>> GetWorkspaceDisplayBehaviorData()
|
||||||
|
{
|
||||||
|
yield return new("Toggle the overlay: the chat uses all the space, workspaces are temporarily shown", WorkspaceDisplayBehavior.TOGGLE_OVERLAY);
|
||||||
|
yield return new("Toggle the sidebar: show the workspaces next to the chat when desired", WorkspaceDisplayBehavior.TOGGLE_SIDEBAR);
|
||||||
|
yield return new("Sidebar is always visible: show the workspaces next to the chat all the time", WorkspaceDisplayBehavior.SIDEBAR_ALWAYS_VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
public static IEnumerable<ConfigurationSelectData<NavBehavior>> GetNavBehaviorData()
|
public static IEnumerable<ConfigurationSelectData<NavBehavior>> GetNavBehaviorData()
|
||||||
{
|
{
|
||||||
yield return new("Navigation expands on mouse hover", NavBehavior.EXPAND_ON_HOVER);
|
yield return new("Navigation expands on mouse hover", NavBehavior.EXPAND_ON_HOVER);
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
namespace AIStudio.Settings.DataModel;
|
||||||
|
|
||||||
|
public sealed class Bias
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The unique identifier of the bias.
|
||||||
|
/// </summary>
|
||||||
|
public Guid Id { get; init; } = Guid.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// In which category the bias is located.
|
||||||
|
/// </summary>
|
||||||
|
public BiasCategory Category { get; set; } = BiasCategory.NONE;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The bias name.
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; init; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The bias description.
|
||||||
|
/// </summary>
|
||||||
|
public string Description { get; init; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Related bias.
|
||||||
|
/// </summary>
|
||||||
|
public IReadOnlyList<Guid> Related { get; init; } = [];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Related links.
|
||||||
|
/// </summary>
|
||||||
|
public IReadOnlyList<string> Links { get; init; } = [];
|
||||||
|
}
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,11 @@
|
|||||||
|
namespace AIStudio.Settings.DataModel;
|
||||||
|
|
||||||
|
public enum BiasCategory
|
||||||
|
{
|
||||||
|
NONE,
|
||||||
|
|
||||||
|
WHAT_SHOULD_WE_REMEMBER,
|
||||||
|
TOO_MUCH_INFORMATION,
|
||||||
|
NOT_ENOUGH_MEANING,
|
||||||
|
NEED_TO_ACT_FAST,
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
namespace AIStudio.Settings.DataModel;
|
||||||
|
|
||||||
|
public static class BiasCategoryExtensions
|
||||||
|
{
|
||||||
|
public static string ToName(this BiasCategory biasCategory) => biasCategory switch
|
||||||
|
{
|
||||||
|
BiasCategory.WHAT_SHOULD_WE_REMEMBER => "What should we remember?",
|
||||||
|
BiasCategory.TOO_MUCH_INFORMATION => "Too much information",
|
||||||
|
BiasCategory.NOT_ENOUGH_MEANING => "Not enough meaning",
|
||||||
|
BiasCategory.NEED_TO_ACT_FAST => "Need to act fast",
|
||||||
|
|
||||||
|
_ => "Unknown category",
|
||||||
|
};
|
||||||
|
|
||||||
|
public static string GetThoughts(this BiasCategory biasCategory) => biasCategory switch
|
||||||
|
{
|
||||||
|
BiasCategory.WHAT_SHOULD_WE_REMEMBER =>
|
||||||
|
"""
|
||||||
|
- We store memories differently based on how they were experienced
|
||||||
|
- We reduce events and lists to their key elements
|
||||||
|
- We discard specifics to form generalities
|
||||||
|
- We edit and reinforce some memories after the fact
|
||||||
|
""",
|
||||||
|
|
||||||
|
BiasCategory.TOO_MUCH_INFORMATION =>
|
||||||
|
"""
|
||||||
|
- We notice things already primed in memory or repeated often
|
||||||
|
- Bizarre, funny, visually-striking, or anthropomorphic things stick out more than non-bizarre/unfunny things
|
||||||
|
- We notice when something has changed
|
||||||
|
- We are drawn to details that confirm our own existing beliefs
|
||||||
|
- We notice flaws in others more easily than we notice flaws in ourselves
|
||||||
|
""",
|
||||||
|
|
||||||
|
BiasCategory.NOT_ENOUGH_MEANING =>
|
||||||
|
"""
|
||||||
|
- We tend to find stories and patterns even when looking at sparse data
|
||||||
|
- We fill in characteristics from stereotypes, generalities, and prior histories
|
||||||
|
- We imagine things and people we’re familiar with or fond of as better
|
||||||
|
- We simplify probabilities and numbers to make them easier to think about
|
||||||
|
- We project our current mindset and assumptions onto the past and future
|
||||||
|
- We think we know what other people are thinking
|
||||||
|
""",
|
||||||
|
|
||||||
|
BiasCategory.NEED_TO_ACT_FAST =>
|
||||||
|
"""
|
||||||
|
- We favor simple-looking options and complete information over complex, ambiguous options
|
||||||
|
- To avoid mistakes, we aim to preserve autonomy and group status, and avoid irreversible decisions
|
||||||
|
- To get things done, we tend to complete things we’ve invested time & energy in
|
||||||
|
- To stay focused, we favor the immediate, relatable thing in front of us
|
||||||
|
- To act, we must be confident we can make an impact and feel what we do is important
|
||||||
|
""",
|
||||||
|
|
||||||
|
_ => string.Empty,
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -67,4 +67,6 @@ public sealed class Data
|
|||||||
public DataMyTasks MyTasks { get; init; } = new();
|
public DataMyTasks MyTasks { get; init; } = new();
|
||||||
|
|
||||||
public DataJobPostings JobPostings { get; init; } = new();
|
public DataJobPostings JobPostings { get; init; } = new();
|
||||||
|
|
||||||
|
public DataBiasOfTheDay BiasOfTheDay { get; init; } = new();
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
using AIStudio.Provider;
|
||||||
|
|
||||||
|
namespace AIStudio.Settings.DataModel;
|
||||||
|
|
||||||
|
public sealed class DataBiasOfTheDay
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A list of bias IDs that have been used.
|
||||||
|
/// </summary>
|
||||||
|
public List<int> UsedBias { get; set; } = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When was the last bias drawn?
|
||||||
|
/// </summary>
|
||||||
|
public DateOnly DateLastBiasDrawn { get; set; } = DateOnly.MinValue;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Which bias is the bias of the day? This isn't the bias id, but rather the chat id in the bias workspace.
|
||||||
|
/// </summary>
|
||||||
|
public Guid BiasOfTheDayChatId { get; set; } = Guid.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Which bias is the bias of the day?
|
||||||
|
/// </summary>
|
||||||
|
public Guid BiasOfTheDayId { get; set; } = Guid.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Restrict to one bias per day?
|
||||||
|
/// </summary>
|
||||||
|
public bool RestrictOneBiasPerDay { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Preselect any rewrite options?
|
||||||
|
/// </summary>
|
||||||
|
public bool PreselectOptions { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Preselect the language?
|
||||||
|
/// </summary>
|
||||||
|
public CommonLanguages PreselectedTargetLanguage { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Preselect any other language?
|
||||||
|
/// </summary>
|
||||||
|
public string PreselectedOtherLanguage { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The minimum confidence level required for a provider to be considered.
|
||||||
|
/// </summary>
|
||||||
|
public ConfidenceLevel MinimumProviderConfidence { get; set; } = ConfidenceLevel.NONE;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Preselect a profile?
|
||||||
|
/// </summary>
|
||||||
|
public string PreselectedProfile { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Preselect a provider?
|
||||||
|
/// </summary>
|
||||||
|
public string PreselectedProvider { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
@@ -11,4 +11,14 @@ public sealed class DataWorkspace
|
|||||||
/// The chat storage maintenance behavior.
|
/// The chat storage maintenance behavior.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public WorkspaceStorageTemporaryMaintenancePolicy StorageTemporaryMaintenancePolicy { get; set; } = WorkspaceStorageTemporaryMaintenancePolicy.DELETE_OLDER_THAN_90_DAYS;
|
public WorkspaceStorageTemporaryMaintenancePolicy StorageTemporaryMaintenancePolicy { get; set; } = WorkspaceStorageTemporaryMaintenancePolicy.DELETE_OLDER_THAN_90_DAYS;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The behavior used for displaying the workspace.
|
||||||
|
/// </summary>
|
||||||
|
public WorkspaceDisplayBehavior DisplayBehavior { get; set; } = WorkspaceDisplayBehavior.TOGGLE_SIDEBAR;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates whether the sidebar is currently visible.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsSidebarVisible { get; set; } = true;
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
namespace AIStudio.Settings.DataModel;
|
||||||
|
|
||||||
|
public enum WorkspaceDisplayBehavior
|
||||||
|
{
|
||||||
|
TOGGLE_OVERLAY,
|
||||||
|
|
||||||
|
TOGGLE_SIDEBAR,
|
||||||
|
SIDEBAR_ALWAYS_VISIBLE,
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@ public enum Components
|
|||||||
SYNONYMS_ASSISTANT,
|
SYNONYMS_ASSISTANT,
|
||||||
MY_TASKS_ASSISTANT,
|
MY_TASKS_ASSISTANT,
|
||||||
JOB_POSTING_ASSISTANT,
|
JOB_POSTING_ASSISTANT,
|
||||||
|
BIAS_DAY_ASSISTANT,
|
||||||
|
|
||||||
CHAT,
|
CHAT,
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,14 @@ namespace AIStudio.Tools;
|
|||||||
|
|
||||||
public static class ComponentsExtensions
|
public static class ComponentsExtensions
|
||||||
{
|
{
|
||||||
|
public static bool AllowSendTo(this Components component) => component switch
|
||||||
|
{
|
||||||
|
Components.NONE => false,
|
||||||
|
Components.BIAS_DAY_ASSISTANT => false,
|
||||||
|
|
||||||
|
_ => true,
|
||||||
|
};
|
||||||
|
|
||||||
public static string Name(this Components component) => component switch
|
public static string Name(this Components component) => component switch
|
||||||
{
|
{
|
||||||
Components.GRAMMAR_SPELLING_ASSISTANT => "Grammar & Spelling Assistant",
|
Components.GRAMMAR_SPELLING_ASSISTANT => "Grammar & Spelling Assistant",
|
||||||
@@ -59,6 +67,7 @@ public static class ComponentsExtensions
|
|||||||
Components.SYNONYMS_ASSISTANT => settingsManager.ConfigurationData.Synonyms.PreselectOptions ? settingsManager.ConfigurationData.Synonyms.MinimumProviderConfidence : default,
|
Components.SYNONYMS_ASSISTANT => settingsManager.ConfigurationData.Synonyms.PreselectOptions ? settingsManager.ConfigurationData.Synonyms.MinimumProviderConfidence : default,
|
||||||
Components.MY_TASKS_ASSISTANT => settingsManager.ConfigurationData.MyTasks.PreselectOptions ? settingsManager.ConfigurationData.MyTasks.MinimumProviderConfidence : default,
|
Components.MY_TASKS_ASSISTANT => settingsManager.ConfigurationData.MyTasks.PreselectOptions ? settingsManager.ConfigurationData.MyTasks.MinimumProviderConfidence : default,
|
||||||
Components.JOB_POSTING_ASSISTANT => settingsManager.ConfigurationData.JobPostings.PreselectOptions ? settingsManager.ConfigurationData.JobPostings.MinimumProviderConfidence : default,
|
Components.JOB_POSTING_ASSISTANT => settingsManager.ConfigurationData.JobPostings.PreselectOptions ? settingsManager.ConfigurationData.JobPostings.MinimumProviderConfidence : default,
|
||||||
|
Components.BIAS_DAY_ASSISTANT => settingsManager.ConfigurationData.BiasOfTheDay.PreselectOptions ? settingsManager.ConfigurationData.BiasOfTheDay.MinimumProviderConfidence : default,
|
||||||
|
|
||||||
_ => default,
|
_ => default,
|
||||||
};
|
};
|
||||||
@@ -77,6 +86,7 @@ public static class ComponentsExtensions
|
|||||||
Components.SYNONYMS_ASSISTANT => settingsManager.ConfigurationData.Synonyms.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.Synonyms.PreselectedProvider) : default,
|
Components.SYNONYMS_ASSISTANT => settingsManager.ConfigurationData.Synonyms.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.Synonyms.PreselectedProvider) : default,
|
||||||
Components.MY_TASKS_ASSISTANT => settingsManager.ConfigurationData.MyTasks.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.MyTasks.PreselectedProvider) : default,
|
Components.MY_TASKS_ASSISTANT => settingsManager.ConfigurationData.MyTasks.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.MyTasks.PreselectedProvider) : default,
|
||||||
Components.JOB_POSTING_ASSISTANT => settingsManager.ConfigurationData.JobPostings.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.JobPostings.PreselectedProvider) : default,
|
Components.JOB_POSTING_ASSISTANT => settingsManager.ConfigurationData.JobPostings.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.JobPostings.PreselectedProvider) : default,
|
||||||
|
Components.BIAS_DAY_ASSISTANT => settingsManager.ConfigurationData.BiasOfTheDay.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.BiasOfTheDay.PreselectedProvider) : default,
|
||||||
|
|
||||||
Components.CHAT => settingsManager.ConfigurationData.Chat.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.Chat.PreselectedProvider) : default,
|
Components.CHAT => settingsManager.ConfigurationData.Chat.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.Chat.PreselectedProvider) : default,
|
||||||
|
|
||||||
@@ -90,6 +100,7 @@ public static class ComponentsExtensions
|
|||||||
Components.EMAIL_ASSISTANT => settingsManager.ConfigurationData.EMail.PreselectOptions ? settingsManager.ConfigurationData.Profiles.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.EMail.PreselectedProfile) : default,
|
Components.EMAIL_ASSISTANT => settingsManager.ConfigurationData.EMail.PreselectOptions ? settingsManager.ConfigurationData.Profiles.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.EMail.PreselectedProfile) : default,
|
||||||
Components.LEGAL_CHECK_ASSISTANT => settingsManager.ConfigurationData.LegalCheck.PreselectOptions ? settingsManager.ConfigurationData.Profiles.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.LegalCheck.PreselectedProfile) : default,
|
Components.LEGAL_CHECK_ASSISTANT => settingsManager.ConfigurationData.LegalCheck.PreselectOptions ? settingsManager.ConfigurationData.Profiles.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.LegalCheck.PreselectedProfile) : default,
|
||||||
Components.MY_TASKS_ASSISTANT => settingsManager.ConfigurationData.MyTasks.PreselectOptions ? settingsManager.ConfigurationData.Profiles.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.MyTasks.PreselectedProfile) : default,
|
Components.MY_TASKS_ASSISTANT => settingsManager.ConfigurationData.MyTasks.PreselectOptions ? settingsManager.ConfigurationData.Profiles.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.MyTasks.PreselectedProfile) : default,
|
||||||
|
Components.BIAS_DAY_ASSISTANT => settingsManager.ConfigurationData.BiasOfTheDay.PreselectOptions ? settingsManager.ConfigurationData.Profiles.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.BiasOfTheDay.PreselectedProfile) : default,
|
||||||
|
|
||||||
Components.CHAT => settingsManager.ConfigurationData.Chat.PreselectOptions ? settingsManager.ConfigurationData.Profiles.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.Chat.PreselectedProfile) : default,
|
Components.CHAT => settingsManager.ConfigurationData.Chat.PreselectOptions ? settingsManager.ConfigurationData.Profiles.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.Chat.PreselectedProfile) : default,
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ public enum Event
|
|||||||
// Chat events:
|
// Chat events:
|
||||||
HAS_CHAT_UNSAVED_CHANGES,
|
HAS_CHAT_UNSAVED_CHANGES,
|
||||||
RESET_CHAT_STATE,
|
RESET_CHAT_STATE,
|
||||||
|
LOAD_CHAT,
|
||||||
|
CHAT_STREAMING_DONE,
|
||||||
|
|
||||||
// Send events:
|
// Send events:
|
||||||
SEND_TO_GRAMMAR_SPELLING_ASSISTANT,
|
SEND_TO_GRAMMAR_SPELLING_ASSISTANT,
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
namespace AIStudio.Tools;
|
||||||
|
|
||||||
|
public readonly record struct LoadChat(Guid WorkspaceId, Guid ChatId);
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
namespace AIStudio.Tools.Rust;
|
namespace AIStudio.Tools.Rust;
|
||||||
|
|
||||||
public readonly record struct SelectSecretRequest(string Destination, string UserName);
|
public readonly record struct SelectSecretRequest(string Destination, string UserName, bool IsTrying);
|
||||||
@@ -253,24 +253,26 @@ public sealed class RustService : IDisposable
|
|||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Try to get the API key for the given provider.
|
/// Try to get the API key for the given provider.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="provider">The provider to get the API key for.</param>
|
/// <param name="provider">The provider to get the API key for.</param>
|
||||||
|
/// <param name="isTrying">Indicates if we are trying to get the API key. In that case, we don't log errors.</param>
|
||||||
/// <returns>The requested secret.</returns>
|
/// <returns>The requested secret.</returns>
|
||||||
public async Task<RequestedSecret> GetAPIKey(IProvider provider)
|
public async Task<RequestedSecret> GetAPIKey(IProvider provider, bool isTrying = false)
|
||||||
{
|
{
|
||||||
var secretRequest = new SelectSecretRequest($"provider::{provider.Id}::{provider.InstanceName}::api_key", Environment.UserName);
|
var secretRequest = new SelectSecretRequest($"provider::{provider.Id}::{provider.InstanceName}::api_key", Environment.UserName, isTrying);
|
||||||
var result = await this.http.PostAsJsonAsync("/secrets/get", secretRequest, this.jsonRustSerializerOptions);
|
var result = await this.http.PostAsJsonAsync("/secrets/get", secretRequest, this.jsonRustSerializerOptions);
|
||||||
if (!result.IsSuccessStatusCode)
|
if (!result.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
this.logger!.LogError($"Failed to get the API key for provider '{provider.Id}' due to an API issue: '{result.StatusCode}'");
|
if(!isTrying)
|
||||||
|
this.logger!.LogError($"Failed to get the API key for provider '{provider.Id}' due to an API issue: '{result.StatusCode}'");
|
||||||
return new RequestedSecret(false, new EncryptedText(string.Empty), "Failed to get the API key due to an API issue.");
|
return new RequestedSecret(false, new EncryptedText(string.Empty), "Failed to get the API key due to an API issue.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var secret = await result.Content.ReadFromJsonAsync<RequestedSecret>(this.jsonRustSerializerOptions);
|
var secret = await result.Content.ReadFromJsonAsync<RequestedSecret>(this.jsonRustSerializerOptions);
|
||||||
if (!secret.Success)
|
if (!secret.Success && !isTrying)
|
||||||
this.logger!.LogError($"Failed to get the API key for provider '{provider.Id}': '{secret.Issue}'");
|
this.logger!.LogError($"Failed to get the API key for provider '{provider.Id}': '{secret.Issue}'");
|
||||||
|
|
||||||
return secret;
|
return secret;
|
||||||
@@ -307,7 +309,7 @@ public sealed class RustService : IDisposable
|
|||||||
/// <returns>The delete secret response.</returns>
|
/// <returns>The delete secret response.</returns>
|
||||||
public async Task<DeleteSecretResponse> DeleteAPIKey(IProvider provider)
|
public async Task<DeleteSecretResponse> DeleteAPIKey(IProvider provider)
|
||||||
{
|
{
|
||||||
var request = new SelectSecretRequest($"provider::{provider.Id}::{provider.InstanceName}::api_key", Environment.UserName);
|
var request = new SelectSecretRequest($"provider::{provider.Id}::{provider.InstanceName}::api_key", Environment.UserName, false);
|
||||||
var result = await this.http.PostAsJsonAsync("/secrets/delete", request, this.jsonRustSerializerOptions);
|
var result = await this.http.PostAsJsonAsync("/secrets/delete", request, this.jsonRustSerializerOptions);
|
||||||
if (!result.IsSuccessStatusCode)
|
if (!result.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,30 +4,30 @@
|
|||||||
"net8.0": {
|
"net8.0": {
|
||||||
"HtmlAgilityPack": {
|
"HtmlAgilityPack": {
|
||||||
"type": "Direct",
|
"type": "Direct",
|
||||||
"requested": "[1.11.65, )",
|
"requested": "[1.11.70, )",
|
||||||
"resolved": "1.11.65",
|
"resolved": "1.11.70",
|
||||||
"contentHash": "Skse4MVlRcHHyP88x+v/uQrMxTPaBIwQodiQ/y59jxs8vHlqTR5M3jt5Wk+csYFnR4rX6I4ndqDji2M8p9kAzw=="
|
"contentHash": "lwCgdq4H+WXH+lkM7TvJhyEs5uNGzoTud1VmXz2jr30/yOTRtG/oMCour5JMTN0t0fU4uFwFYIrDd98FH2RKsQ=="
|
||||||
},
|
},
|
||||||
"Microsoft.Extensions.FileProviders.Embedded": {
|
"Microsoft.Extensions.FileProviders.Embedded": {
|
||||||
"type": "Direct",
|
"type": "Direct",
|
||||||
"requested": "[8.0.8, )",
|
"requested": "[8.0.10, )",
|
||||||
"resolved": "8.0.8",
|
"resolved": "8.0.10",
|
||||||
"contentHash": "fefQMlaOIQnc7cn7R/GWCwnA6X0tv5pB9ZKIR6I1JZPmYcoCNY7HtLt0bJPMj+F0StrMkwTk2cPtMGtr9zhkoA==",
|
"contentHash": "N/Ow71LLKXbC4fOFoAG7QNyyhgRypd8in8lc92xInZyyNFlBTgGR3R1BV91Wr5+1/l9+Qvo+2Ee2cAth43OP/Q==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.Extensions.FileProviders.Abstractions": "8.0.0"
|
"Microsoft.Extensions.FileProviders.Abstractions": "8.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Microsoft.NET.ILLink.Tasks": {
|
"Microsoft.NET.ILLink.Tasks": {
|
||||||
"type": "Direct",
|
"type": "Direct",
|
||||||
"requested": "[8.0.8, )",
|
"requested": "[8.0.10, )",
|
||||||
"resolved": "8.0.8",
|
"resolved": "8.0.10",
|
||||||
"contentHash": "P8wR6MUWwYXIjPJuBaZgo5zlI/GWI6QEAo6NyVIbPefa9CCkohYu7dP2rD/mrqnjEqfRHyl+h9VZrDoGpELqYg=="
|
"contentHash": "xT8jYjlroY7SLbGtoV9vUTVW/TPgodL4Egc31a444Xe0TMytLZ3UlKQ0kxMZsy/CrWsFB6wtKnSG1SsXcWreew=="
|
||||||
},
|
},
|
||||||
"MudBlazor": {
|
"MudBlazor": {
|
||||||
"type": "Direct",
|
"type": "Direct",
|
||||||
"requested": "[7.8.0, )",
|
"requested": "[7.14.0, )",
|
||||||
"resolved": "7.8.0",
|
"resolved": "7.14.0",
|
||||||
"contentHash": "DivLaZKVkL4z8jVeqa1P2n3u5Dny8l/K1nCLrzp8hI+efdE2Rd1KDkMqoaGdjgV9jCEJ3D35r1+/w6V4yPzuaw==",
|
"contentHash": "hpuNSlI6/BVCe4H6X4BoHijxMffFE1ldunvFzAFZRTGuSGoYC7N6IIUv64MN3F/hkiRllx3gtivTZjivymxIpQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.AspNetCore.Components": "8.0.8",
|
"Microsoft.AspNetCore.Components": "8.0.8",
|
||||||
"Microsoft.AspNetCore.Components.Web": "8.0.8",
|
"Microsoft.AspNetCore.Components.Web": "8.0.8",
|
||||||
@@ -36,12 +36,12 @@
|
|||||||
},
|
},
|
||||||
"MudBlazor.Markdown": {
|
"MudBlazor.Markdown": {
|
||||||
"type": "Direct",
|
"type": "Direct",
|
||||||
"requested": "[7.8.0, )",
|
"requested": "[7.14.0, )",
|
||||||
"resolved": "7.8.0",
|
"resolved": "7.14.0",
|
||||||
"contentHash": "XaspHsS5I9osnna46Q/tH7cy3OlgG7dnycZgn7KhkTBNqpFzelrBoMkf/YFjRWSWEHEeO2o8AKjrG6uo99OYsw==",
|
"contentHash": "c6kFfMgUxKxYK1AkGHRNg5B9jw+iwxelBuDpaI5N+guOleT37BxYetYlD0iOew/n1plhobynUJn3Kk4MXhv6RA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Markdig": "0.37.0",
|
"Markdig": "0.37.0",
|
||||||
"MudBlazor": "7.8.0"
|
"MudBlazor": "7.14.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ReverseMarkdown": {
|
"ReverseMarkdown": {
|
||||||
|
|||||||
@@ -60,6 +60,10 @@
|
|||||||
background-color: initial !important;
|
background-color: initial !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.improvedDiff .wikEdDiffNoChange {
|
||||||
|
background-color: initial !important;
|
||||||
|
}
|
||||||
|
|
||||||
.improvedDiff .wikEdDiffDelete {
|
.improvedDiff .wikEdDiffDelete {
|
||||||
text-decoration-line: line-through;
|
text-decoration-line: line-through;
|
||||||
text-decoration-style: double;
|
text-decoration-style: double;
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
# v0.9.13, build 188 (2024-10-07 11:18 UTC)
|
||||||
|
- Allow the use of an API key for self-hosted `ollama` instances. Useful when using `ollama` with, e.g., Open WebUI.
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
# v0.9.14, build 189 (2024-10-18 08:48 UTC)
|
||||||
|
- Added our first contributor @richard-stanton to the supporter page.
|
||||||
|
- Upgraded to .NET 8.0.10
|
||||||
|
- Upgraded to Rust 1.82.0
|
||||||
|
- Upgraded to Tauri 1.8.1
|
||||||
|
- Upgraded to MudBlazor 7.13.0
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
# v0.9.15, build 190 (2024-10-28 15:04 UTC)
|
||||||
|
- Added bias-of-the-day assistant: the assistant will provide a cognitive bias every day. The bias is explained in detail, and the user can ask questions about it.
|
||||||
|
- Upgraded `MudBlazor` to v7.14.0.
|
||||||
|
- Upgraded `MudBlazor.Markdown` to v7.14.0.
|
||||||
|
- Upgraded `tokio` to v1.41.
|
||||||
|
- Upgraded `keyring` to v3.6.
|
||||||
|
- Upgraded `arboard` to v3.4.1.
|
||||||
|
- Upgraded `HtmlAgilityPack` to v1.11.70.
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
# v0.9.16, build 191 (2024-11-02 22:04 UTC)
|
||||||
|
- Added our second financial contributor: Thanks `peerschuett` for supporting AI Studio financially.
|
||||||
|
- Added multiple workspace display options: toggle the workspace overlay (this is the previous behavior), toggle the workspace sidebar, or permanently display the workspace sidebar.
|
||||||
|
- Improved the layout of the app window, for example, in full-screen mode on large or high-resolution monitors.
|
||||||
|
- Fixed the "send to" issue, where you could select the bias-of-the-day assistant as destination.
|
||||||
|
- Fixed the appearance of the "no diff" message for text diffs when the dark mode is enabled.
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
# v0.9.17, build 192 (2024-11-03 11:11 UTC)
|
||||||
|
- Added new Anthropic model `claude-3-5-sonnet-20241022` as well as the aliases `claude-3-5-sonnet-latest` and `claude-3-opus-latest`.
|
||||||
+1
-1
@@ -1 +1 @@
|
|||||||
.mud-markdown-body code:not(.hljs){background:var(--mud-palette-action-disabled-background);color:var(--mud-palette-text-primary)!important;padding:2.5px 7.5px;border-radius:5px}pre code.hljs{display:block!important;overflow-x:auto;padding:1em}.mud-markdown-body .snippet-clipboard-content{position:relative!important}.mud-markdown-body .snippet-clipboard-content:hover>.snippet-clipboard-copy-icon{display:block!important}.mud-markdown-body .snippet-clipboard-content .snippet-clipboard-copy-icon{position:absolute;display:none;top:0;right:0}.mud-markdown-body blockquote{border-left:.25em solid var(--mud-palette-text-disabled);color:var(--mud-palette-text-secondary);background-color:var(--mud-palette-table-hover);padding:.25em 1em;margin:.5em 0 1.25em}.mud-markdown-body blockquote p{margin-bottom:0!important}.mud-markdown-body table{margin:1.25em 0}.mud-markdown-body .mud-link:hover{cursor:pointer!important}.mud-markdown-body ul{list-style-type:disc}.mud-markdown-body ol,.mud-markdown-body ul{padding-left:2em;margin-bottom:1.25em!important}.mud-markdown-body ul ul{list-style-type:circle;margin-bottom:0!important}.mud-markdown-body ul ul ul{list-style-type:square;margin-bottom:0!important}.mud-markdown-body li{display:list-item!important;text-align:-webkit-match-parent}.mud-markdown-body h1,.mud-markdown-body h2{border-bottom:1px solid var(--mud-palette-text-disabled);padding-bottom:.125em;margin-bottom:.4em}.mud-markdown-body h1,.mud-markdown-body h2,.mud-markdown-body h3,.mud-markdown-body h4,.mud-markdown-body h5,.mud-markdown-body h6{scroll-margin-top:5rem;margin-top:.25em;word-wrap:break-word;margin-bottom:.3em!important}.mud-markdown-body .mud-divider{margin:.5em 0;height:.25em}.mud-markdown-body p{margin-bottom:1.25em!important}.mud-markdown-body .mud-expand-panel p,.mud-markdown-body li p{margin-bottom:0!important}.mud-markdown-body img{max-width:100%}
|
.mud-markdown-body code:not(.hljs){background:var(--mud-palette-action-disabled-background);color:var(--mud-palette-text-primary)!important;padding:2.5px 7.5px;border-radius:5px}pre code.hljs{display:block!important;overflow-x:auto;padding:1em}.mud-markdown-body .snippet-clipboard-content{position:relative!important}.mud-markdown-body .snippet-clipboard-content:hover>.snippet-clipboard-copy-icon{display:block!important}.mud-markdown-body .snippet-clipboard-content .snippet-clipboard-copy-icon{position:absolute;display:none;top:0;right:0}.mud-markdown-body blockquote{border-left:.25em solid var(--mud-palette-text-disabled);color:var(--mud-palette-text-secondary);background-color:var(--mud-palette-table-hover);padding:.25em 1em;margin:.5em 0 1.25em}.mud-markdown-body blockquote p{margin-bottom:0!important}.mud-markdown-body table{margin:1.25em 0}.mud-markdown-body .mud-link:hover{cursor:pointer!important}.mud-markdown-body ul{list-style-type:disc}.mud-markdown-body ol,.mud-markdown-body ul{padding-left:2em;margin-bottom:1.25em!important}.mud-markdown-body ul ul{list-style-type:circle;margin-bottom:0!important}.mud-markdown-body ul ul ul{list-style-type:square;margin-bottom:0!important}.mud-markdown-body li{display:list-item!important;text-align:-webkit-match-parent}.mud-markdown-body h1,.mud-markdown-body h2{border-bottom:1px solid var(--mud-palette-text-disabled);padding-bottom:.125em;margin-bottom:.4em}.mud-markdown-body h1,.mud-markdown-body h2,.mud-markdown-body h3,.mud-markdown-body h4,.mud-markdown-body h5,.mud-markdown-body h6{scroll-margin-top:5rem;margin-top:.25em;word-wrap:break-word;margin-bottom:.3em!important}.mud-markdown-body .mud-divider{margin:.5em 0;height:.25em}.mud-markdown-body p{margin-bottom:1.25em!important}.mud-markdown-body .mud-expand-panel p,.mud-markdown-body li p{margin-bottom:0!important}.mud-markdown-body p .markdown-error{white-space:pre}.mud-markdown-body img{max-width:100%}
|
||||||
+1
-1
@@ -1 +1 @@
|
|||||||
(()=>{var e={2689:e=>{e.exports=function(e){var t="built_in",a={},n={begin:"}",className:t,endsParent:!0},i={begin:"{",end:"}",contains:[e.QUOTE_STRING_MODE,"self"]},r=e.COMMENT("@\\*","\\*@",{relevance:10}),o={begin:"@[A-Za-z0-9\\._:-]+",returnBegin:!0,end:"(\\r|\\n|<|\\s|\"|')",subLanguage:"csharp",contains:[{begin:"@",className:t},{begin:"\\[",end:"\\]",skip:!0},{begin:"\\(",end:"\\)",skip:!0}],returnEnd:!0},s={begin:"[@]{0,1}<text>",returnBegin:!0,end:"</text>",returnEnd:!0,subLanguage:"cshtml-razor",contains:[{begin:"[@]{0,1}<text>",className:t},{begin:"</text>",className:t,endsParent:!0}]},l={begin:"@\\(",end:"\\)",returnBegin:!0,returnEnd:!0,subLanguage:"csharp",contains:[{begin:"@\\(",className:t},{begin:"\\(",end:"\\)",subLanguage:"csharp",contains:[e.QUOTE_STRING_MODE,"self",s]},s,{begin:"\\)",className:t,endsParent:!0}]},c=function(e,t){var a={endsWithParent:!0,illegal:/</,relevance:0,contains:[{className:"attr",begin:"[A-Za-z0-9\\._:-]+",relevance:0},{begin:/=\s*/,relevance:0,contains:[{className:"string",variants:[{begin:/"/,end:/"/,contains:t},{begin:/'/,end:/'/,contains:t},{begin:/[^\s"'=<>`]+/}]}]}]};return[{className:"meta",begin:"<!DOCTYPE",end:">",relevance:10,contains:[{begin:"\\[",end:"\\]"}]},e.COMMENT("\x3c!--","--\x3e",{relevance:10}),{begin:"<\\!\\[CDATA\\[",end:"\\]\\]>",relevance:10},{className:"meta",begin:/<\?xml/,end:/\?>/,relevance:10},{className:"tag",begin:"<style(?=\\s|>|$)",end:">",keywords:{name:"style"},contains:[a],starts:{end:"</style>",returnEnd:!0,subLanguage:["css","xml"]}},{className:"tag",begin:"<script(?=\\s|>|$)",end:">",keywords:{name:"script"},contains:[a],starts:{end:"<\/script>",returnEnd:!0,subLanguage:["actionscript","javascript","handlebars","xml"]}},{className:"tag",begin:"</?",end:"/?>",contains:[{className:"name",begin:/[^\/><\s]+/,relevance:0},a]}].concat(t)}(e,[o,l]),_="^\\s*@(page|model|using|inherits|inject|layout)",d={begin:_+"[^\\r\\n{\\(]*$",end:"$",returnBegin:!0,returnEnd:!0,contains:[{begin:_,className:t},{variants:[{begin:"\\r|\\n",endsParent:!0},{begin:"\\s[^\\r\\n]+",end:"$"},{begin:"$"}],className:"type",endsParent:!0}]},m={variants:[{begin:"@\\{",end:"}"},{begin:"@code\\s*\\{",end:"}"}],returnBegin:!0,returnEnd:!0,subLanguage:"csharp",contains:[{begin:"@(code\\s*)?\\{",className:t},a,{begin:"{",end:"}",contains:["self"],skip:!0},n]},p={begin:"^\\s*@helper[\\s]*[^{]+[\\s]*{",returnBegin:!0,returnEnd:!0,end:"}",subLanguage:"cshtml-razor",contains:[{begin:"@helper",className:t},{begin:"{",className:t},n]},u=[{begin:"@for[\\s]*\\([^{]+[\\s]*{",end:"}"},{begin:"@if[\\s]*\\([^{]+[\\s]*{",end:"}"},{begin:"@switch[\\s]*\\([^{]+[\\s]*{",end:"}"},{begin:"@while[\\s]*\\([^{]+[\\s]*{",end:"}"},{begin:"@using[\\s]*\\([^{]+[\\s]*{",end:"}"},{begin:"@lock[\\s]*\\([^{]+[\\s]*{",end:"}"},{begin:"@foreach[\\s]*\\([^{]+[\\s]*{",end:"}"}],g={variants:u,returnBegin:!0,returnEnd:!0,subLanguage:"csharp",contains:[{variants:u.map((function(e){return{begin:e.begin}})),returnBegin:!0,contains:[{begin:"@",className:t},{variants:u.map((function(e){return{begin:e.begin.substr(1,e.begin.length-2)}})),subLanguage:"csharp"},{begin:"{",className:t}]},a,{variants:[{begin:"}[\\s]*else\\sif[\\s]*\\([^{]+[\\s]*{"},{begin:"}[\\s]*else[\\s]*{"}],returnBegin:!0,contains:[{begin:"}",className:t},{variants:[{begin:"[\\s]*else\\sif[\\s]*\\([^{]+[\\s]*{"},{begin:"[\\s]*else[\\s]*"}],subLanguage:"csharp"},{begin:"{",className:t}]},i,n]},E={begin:"@try[\\s]*{",end:"}",returnBegin:!0,returnEnd:!0,subLanguage:"csharp",contains:[{begin:"@",className:t},{begin:"try[\\s]*{",subLanguage:"csharp"},{variants:[{begin:"}[\\s]*catch[\\s]*\\([^\\)]+\\)[\\s]*{"},{begin:"}[\\s]*finally[\\s]*{"}],returnBegin:!0,contains:[{begin:"}",className:t},{variants:[{begin:"[\\s]*catch[\\s]*\\([^\\)]+\\)[\\s]*"},{begin:"[\\s]*finally[\\s]*"}],subLanguage:"csharp"},{begin:"{",className:t}]},a,i,n]},S="@section[\\s]+[a-zA-Z0-9]+[\\s]*{",b=[d,p,m,g,{begin:S,returnBegin:!0,returnEnd:!0,end:"}",subLanguage:"cshtml-razor",contains:[{begin:S,className:t},i,n]},{begin:"@await ",returnBegin:!0,subLanguage:"csharp",end:"(\\r|\\n|<|\\s)",contains:[{begin:"@await ",className:t},{begin:"[<\\r\\n]",endsParent:!0}]},E,{variants:[{begin:"@@"},{begin:"[a-zA-Z]+@"}],skip:!0},s,r,l,{className:"meta",begin:"<!DOCTYPE",end:">",relevance:10,contains:[{begin:"\\[",end:"\\]"}]},{begin:"<\\!\\[CDATA\\[",end:"\\]\\]>",relevance:10}].concat(c);return[m,g,E].forEach((function(e){var t=b.filter((function(t){return t!==e})),n=e.contains.indexOf(a);e.contains.splice.apply(e.contains,[n,1].concat(t))})),{aliases:["cshtml","razor","razor-cshtml","cshtml-razor"],contains:b}}},3390:e=>{function t(e){return e instanceof Map?e.clear=e.delete=e.set=function(){throw new Error("map is read-only")}:e instanceof Set&&(e.add=e.clear=e.delete=function(){throw new Error("set is read-only")}),Object.freeze(e),Object.getOwnPropertyNames(e).forEach((a=>{const n=e[a],i=typeof n;"object"!==i&&"function"!==i||Object.isFrozen(n)||t(n)})),e}class a{constructoLine truncated
|
(()=>{var e={2224:e=>{e.exports=function(e){var t="built_in",a={},n={begin:"}",className:t,endsParent:!0},r={begin:"{",end:"}",contains:[e.QUOTE_STRING_MODE,"self"]},i=e.COMMENT("@\\*","\\*@",{relevance:10}),o={begin:"@[A-Za-z0-9\\._:-]+",returnBegin:!0,end:"(\\r|\\n|<|\\s|\"|')",subLanguage:"csharp",contains:[{begin:"@",className:t},{begin:"\\[",end:"\\]",skip:!0},{begin:"\\(",end:"\\)",skip:!0}],returnEnd:!0},s={begin:"[@]{0,1}<text>",returnBegin:!0,end:"</text>",returnEnd:!0,subLanguage:"cshtml-razor",contains:[{begin:"[@]{0,1}<text>",className:t},{begin:"</text>",className:t,endsParent:!0}]},l={begin:"@\\(",end:"\\)",returnBegin:!0,returnEnd:!0,subLanguage:"csharp",contains:[{begin:"@\\(",className:t},{begin:"\\(",end:"\\)",subLanguage:"csharp",contains:[e.QUOTE_STRING_MODE,"self",s]},s,{begin:"\\)",className:t,endsParent:!0}]},c=function(e,t){var a={endsWithParent:!0,illegal:/</,relevance:0,contains:[{className:"attr",begin:"[A-Za-z0-9\\._:-]+",relevance:0},{begin:/=\s*/,relevance:0,contains:[{className:"string",variants:[{begin:/"/,end:/"/,contains:t},{begin:/'/,end:/'/,contains:t},{begin:/[^\s"'=<>`]+/}]}]}]};return[{className:"meta",begin:"<!DOCTYPE",end:">",relevance:10,contains:[{begin:"\\[",end:"\\]"}]},e.COMMENT("\x3c!--","--\x3e",{relevance:10}),{begin:"<\\!\\[CDATA\\[",end:"\\]\\]>",relevance:10},{className:"meta",begin:/<\?xml/,end:/\?>/,relevance:10},{className:"tag",begin:"<style(?=\\s|>|$)",end:">",keywords:{name:"style"},contains:[a],starts:{end:"</style>",returnEnd:!0,subLanguage:["css","xml"]}},{className:"tag",begin:"<script(?=\\s|>|$)",end:">",keywords:{name:"script"},contains:[a],starts:{end:"<\/script>",returnEnd:!0,subLanguage:["actionscript","javascript","handlebars","xml"]}},{className:"tag",begin:"</?",end:"/?>",contains:[{className:"name",begin:/[^\/><\s]+/,relevance:0},a]}].concat(t)}(e,[o,l]),_="^\\s*@(page|model|using|inherits|inject|layout)",d={begin:_+"[^\\r\\n{\\(]*$",end:"$",returnBegin:!0,returnEnd:!0,contains:[{begin:_,className:t},{variants:[{begin:"\\r|\\n",endsParent:!0},{begin:"\\s[^\\r\\n]+",end:"$"},{begin:"$"}],className:"type",endsParent:!0}]},m={variants:[{begin:"@\\{",end:"}"},{begin:"@code\\s*\\{",end:"}"}],returnBegin:!0,returnEnd:!0,subLanguage:"csharp",contains:[{begin:"@(code\\s*)?\\{",className:t},a,{begin:"{",end:"}",contains:["self"],skip:!0},n]},p={begin:"^\\s*@helper[\\s]*[^{]+[\\s]*{",returnBegin:!0,returnEnd:!0,end:"}",subLanguage:"cshtml-razor",contains:[{begin:"@helper",className:t},{begin:"{",className:t},n]},u=[{begin:"@for[\\s]*\\([^{]+[\\s]*{",end:"}"},{begin:"@if[\\s]*\\([^{]+[\\s]*{",end:"}"},{begin:"@switch[\\s]*\\([^{]+[\\s]*{",end:"}"},{begin:"@while[\\s]*\\([^{]+[\\s]*{",end:"}"},{begin:"@using[\\s]*\\([^{]+[\\s]*{",end:"}"},{begin:"@lock[\\s]*\\([^{]+[\\s]*{",end:"}"},{begin:"@foreach[\\s]*\\([^{]+[\\s]*{",end:"}"}],g={variants:u,returnBegin:!0,returnEnd:!0,subLanguage:"csharp",contains:[{variants:u.map((function(e){return{begin:e.begin}})),returnBegin:!0,contains:[{begin:"@",className:t},{variants:u.map((function(e){return{begin:e.begin.substr(1,e.begin.length-2)}})),subLanguage:"csharp"},{begin:"{",className:t}]},a,{variants:[{begin:"}[\\s]*else\\sif[\\s]*\\([^{]+[\\s]*{"},{begin:"}[\\s]*else[\\s]*{"}],returnBegin:!0,contains:[{begin:"}",className:t},{variants:[{begin:"[\\s]*else\\sif[\\s]*\\([^{]+[\\s]*{"},{begin:"[\\s]*else[\\s]*"}],subLanguage:"csharp"},{begin:"{",className:t}]},r,n]},E={begin:"@try[\\s]*{",end:"}",returnBegin:!0,returnEnd:!0,subLanguage:"csharp",contains:[{begin:"@",className:t},{begin:"try[\\s]*{",subLanguage:"csharp"},{variants:[{begin:"}[\\s]*catch[\\s]*\\([^\\)]+\\)[\\s]*{"},{begin:"}[\\s]*finally[\\s]*{"}],returnBegin:!0,contains:[{begin:"}",className:t},{variants:[{begin:"[\\s]*catch[\\s]*\\([^\\)]+\\)[\\s]*"},{begin:"[\\s]*finally[\\s]*"}],subLanguage:"csharp"},{begin:"{",className:t}]},a,r,n]},S="@section[\\s]+[a-zA-Z0-9]+[\\s]*{",b=[d,p,m,g,{begin:S,returnBegin:!0,returnEnd:!0,end:"}",subLanguage:"cshtml-razor",contains:[{begin:S,className:t},r,n]},{begin:"@await ",returnBegin:!0,subLanguage:"csharp",end:"(\\r|\\n|<|\\s)",contains:[{begin:"@await ",className:t},{begin:"[<\\r\\n]",endsParent:!0}]},E,{variants:[{begin:"@@"},{begin:"[a-zA-Z]+@"}],skip:!0},s,i,l,{className:"meta",begin:"<!DOCTYPE",end:">",relevance:10,contains:[{begin:"\\[",end:"\\]"}]},{begin:"<\\!\\[CDATA\\[",end:"\\]\\]>",relevance:10}].concat(c);return[m,g,E].forEach((function(e){var t=b.filter((function(t){return t!==e})),n=e.contains.indexOf(a);e.contains.splice.apply(e.contains,[n,1].concat(t))})),{aliases:["cshtml","razor","razor-cshtml","cshtml-razor"],contains:b}}},8416:e=>{function t(e){return e instanceof Map?e.clear=e.delete=e.set=function(){throw new Error("map is read-only")}:e instanceof Set&&(e.add=e.clear=e.delete=function(){throw new Error("set is read-only")}),Object.freeze(e),Object.getOwnPropertyNames(e).forEach((a=>{const n=e[a],r=typeof n;"object"!==r&&"function"!==r||Object.isFrozen(n)||t(n)})),e}class a{constructoLine truncated
|
||||||
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 33 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.9 KiB |
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -2,4 +2,4 @@
|
|||||||
* MudBlazor (https://mudblazor.com/)
|
* MudBlazor (https://mudblazor.com/)
|
||||||
* Copyright (c) 2021 MudBlazor
|
* Copyright (c) 2021 MudBlazor
|
||||||
* Licensed under MIT (https://github.com/MudBlazor/MudBlazor/blob/master/LICENSE)
|
* Licensed under MIT (https://github.com/MudBlazor/MudBlazor/blob/master/LICENSE)
|
||||||
*/.mud-primary{background-color:var(--mud-palette-primary) !important}.mud-primary-text{color:var(--mud-palette-primary) !important;--mud-ripple-color: var(--mud-palette-primary) !important}.mud-primary-hover{background-color:var(--mud-palette-primary-hover) !important}@media(hover: hover)and (pointer: fine){.hover\:mud-primary-hover:hover{background-color:var(--mud-palette-primary-hover) !important}}.hover\:mud-primary-hover:focus-visible,.hover\:mud-primary-hover:active{background-color:var(--mud-palette-primary-hover) !important}.mud-border-primary{border-color:var(--mud-palette-primary) !important}.mud-theme-primary{color:var(--mud-palette-primary-text) !important;background-color:var(--mud-palette-primary) !important}.mud-secondary{background-color:var(--mud-palette-secondary) !important}.mud-secondary-text{color:var(--mud-palette-secondary) !important;--mud-ripple-color: var(--mud-palette-secondary) !important}.mud-secondary-hover{background-color:var(--mud-palette-secondary-hover) !important}@media(hover: hover)and (pointer: fine){.hover\:mud-secondary-hover:hover{background-color:var(--mud-palette-secondary-hover) !important}}.hover\:mud-secondary-hover:focus-visible,.hover\:mud-secondary-hover:active{background-color:var(--mud-palette-secondary-hover) !important}.mud-border-secondary{border-color:var(--mud-palette-secondary) !important}.mud-theme-secondary{color:var(--mud-palette-secondary-text) !important;background-color:var(--mud-palette-secondary) !important}.mud-tertiary{background-color:var(--mud-palette-tertiary) !important}.mud-tertiary-text{color:var(--mud-palette-tertiary) !important;--mud-ripple-color: var(--mud-palette-tertiary) !important}.mud-tertiary-hover{background-color:var(--mud-palette-tertiary-hover) !important}@media(hover: hover)and (pointer: fine){.hover\:mud-tertiary-hover:hover{background-color:var(--mud-palette-tertiary-hover) !important}}.hover\:mud-tertiary-hover:focus-visible,.hover\:mud-tertiary-hover:active{background-color:var(--mud-palette-tertiary-hover) !important}.mud-border-tertiary{border-color:var(--mud-palette-tertiary) !important}.mud-theme-tertiary{color:var(--mud-palette-tertiary-text) !important;background-color:var(--mud-palette-tertiary) !important}.mud-info{background-color:var(--mud-palette-info) !important}.mud-info-text{color:var(--mud-palette-info) !important;--mud-ripple-color: var(--mud-palette-info) !important}.mud-info-hover{background-color:var(--mud-palette-info-hover) !important}@media(hover: hover)and (pointer: fine){.hover\:mud-info-hover:hover{background-color:var(--mud-palette-info-hover) !important}}.hover\:mud-info-hover:focus-visible,.hover\:mud-info-hover:active{background-color:var(--mud-palette-info-hover) !important}.mud-border-info{border-color:var(--mud-palette-info) !important}.mud-theme-info{color:var(--mud-palette-info-text) !important;background-color:var(--mud-palette-info) !important}.mud-success{background-color:var(--mud-palette-success) !important}.mud-success-text{color:var(--mud-palette-success) !important;--mud-ripple-color: var(--mud-palette-success) !important}.mud-success-hover{background-color:var(--mud-palette-success-hover) !important}@media(hover: hover)and (pointer: fine){.hover\:mud-success-hover:hover{background-color:var(--mud-palette-success-hover) !important}}.hover\:mud-success-hover:focus-visible,.hover\:mud-success-hover:active{background-color:var(--mud-palette-success-hover) !important}.mud-border-success{border-color:var(--mud-palette-success) !important}.mud-theme-success{color:var(--mud-palette-success-text) !important;background-color:var(--mud-palette-success) !important}.mud-warning{background-color:var(--mud-palette-warning) !important}.mud-warning-text{color:var(--mud-palette-warning) !important;--mud-ripple-color: var(--mud-palette-warning) !important}.mud-warning-hover{background-color:var(--mud-palette-warning-hover) !important}@media(hover: hover)and (pointer: fine){.hover\:mud-warning-hover:hover{background-color:var(--mud-palette-warning-hover) !important}}.hover\:mud-warning-hover:focus-visible,.hover\:mud-warning-hover:active{background-color:var(--mud-palette-warning-hover) !important}.mud-border-warning{border-color:var(--mud-palette-warning) !important}.mud-theme-warning{color:var(--mud-palette-warning-text) !important;background-color:var(--mud-palette-warning) !important}.mud-error{background-color:var(--mud-palette-error) !important}.mud-error-text{color:var(--mud-palette-error) !important;--mud-ripple-color: var(--mud-palette-error) !important}.mud-error-hover{background-color:var(--mud-palette-error-hover) !important}@media(hover: hover)and (pointer: fine){.hover\:mud-error-hover:hover{background-color:var(--mud-palette-error-hover) !important}}.hover\:mud-error-hover:focus-visible,.hover\:mud-error-hover:active{background-color:var(--mud-palette-error-hover) !important}.mud-border-error{border-color:var(--mud-palette-error) !important}.mud-theme-error{color:var(--mud-paleLine truncated
|
*/.mud-primary{background-color:var(--mud-palette-primary) !important}.mud-primary-text{color:var(--mud-palette-primary) !important;--mud-ripple-color: var(--mud-palette-primary) !important}.mud-primary-hover{background-color:var(--mud-palette-primary-hover) !important}@media(hover: hover)and (pointer: fine){.hover\:mud-primary-hover:hover{background-color:var(--mud-palette-primary-hover) !important}}.hover\:mud-primary-hover:focus-visible,.hover\:mud-primary-hover:active{background-color:var(--mud-palette-primary-hover) !important}.mud-border-primary{border-color:var(--mud-palette-primary) !important}.mud-theme-primary{color:var(--mud-palette-primary-text) !important;background-color:var(--mud-palette-primary) !important}.mud-secondary{background-color:var(--mud-palette-secondary) !important}.mud-secondary-text{color:var(--mud-palette-secondary) !important;--mud-ripple-color: var(--mud-palette-secondary) !important}.mud-secondary-hover{background-color:var(--mud-palette-secondary-hover) !important}@media(hover: hover)and (pointer: fine){.hover\:mud-secondary-hover:hover{background-color:var(--mud-palette-secondary-hover) !important}}.hover\:mud-secondary-hover:focus-visible,.hover\:mud-secondary-hover:active{background-color:var(--mud-palette-secondary-hover) !important}.mud-border-secondary{border-color:var(--mud-palette-secondary) !important}.mud-theme-secondary{color:var(--mud-palette-secondary-text) !important;background-color:var(--mud-palette-secondary) !important}.mud-tertiary{background-color:var(--mud-palette-tertiary) !important}.mud-tertiary-text{color:var(--mud-palette-tertiary) !important;--mud-ripple-color: var(--mud-palette-tertiary) !important}.mud-tertiary-hover{background-color:var(--mud-palette-tertiary-hover) !important}@media(hover: hover)and (pointer: fine){.hover\:mud-tertiary-hover:hover{background-color:var(--mud-palette-tertiary-hover) !important}}.hover\:mud-tertiary-hover:focus-visible,.hover\:mud-tertiary-hover:active{background-color:var(--mud-palette-tertiary-hover) !important}.mud-border-tertiary{border-color:var(--mud-palette-tertiary) !important}.mud-theme-tertiary{color:var(--mud-palette-tertiary-text) !important;background-color:var(--mud-palette-tertiary) !important}.mud-info{background-color:var(--mud-palette-info) !important}.mud-info-text{color:var(--mud-palette-info) !important;--mud-ripple-color: var(--mud-palette-info) !important}.mud-info-hover{background-color:var(--mud-palette-info-hover) !important}@media(hover: hover)and (pointer: fine){.hover\:mud-info-hover:hover{background-color:var(--mud-palette-info-hover) !important}}.hover\:mud-info-hover:focus-visible,.hover\:mud-info-hover:active{background-color:var(--mud-palette-info-hover) !important}.mud-border-info{border-color:var(--mud-palette-info) !important}.mud-theme-info{color:var(--mud-palette-info-text) !important;background-color:var(--mud-palette-info) !important}.mud-success{background-color:var(--mud-palette-success) !important}.mud-success-text{color:var(--mud-palette-success) !important;--mud-ripple-color: var(--mud-palette-success) !important}.mud-success-hover{background-color:var(--mud-palette-success-hover) !important}@media(hover: hover)and (pointer: fine){.hover\:mud-success-hover:hover{background-color:var(--mud-palette-success-hover) !important}}.hover\:mud-success-hover:focus-visible,.hover\:mud-success-hover:active{background-color:var(--mud-palette-success-hover) !important}.mud-border-success{border-color:var(--mud-palette-success) !important}.mud-theme-success{color:var(--mud-palette-success-text) !important;background-color:var(--mud-palette-success) !important}.mud-warning{background-color:var(--mud-palette-warning) !important}.mud-warning-text{color:var(--mud-palette-warning) !important;--mud-ripple-color: var(--mud-palette-warning) !important}.mud-warning-hover{background-color:var(--mud-palette-warning-hover) !important}@media(hover: hover)and (pointer: fine){.hover\:mud-warning-hover:hover{background-color:var(--mud-palette-warning-hover) !important}}.hover\:mud-warning-hover:focus-visible,.hover\:mud-warning-hover:active{background-color:var(--mud-palette-warning-hover) !important}.mud-border-warning{border-color:var(--mud-palette-warning) !important}.mud-theme-warning{color:var(--mud-palette-warning-text) !important;background-color:var(--mud-palette-warning) !important}.mud-error{background-color:var(--mud-palette-error) !important}.mud-error-text{color:var(--mud-palette-error) !important;--mud-ripple-color: var(--mud-palette-error) !important}.mud-error-hover{background-color:var(--mud-palette-error-hover) !important}@media(hover: hover)and (pointer: fine){.hover\:mud-error-hover:hover{background-color:var(--mud-palette-error-hover) !important}}.hover\:mud-error-hover:focus-visible,.hover\:mud-error-hover:active{background-color:var(--mud-palette-error-hover) !important}.mud-border-error{border-color:var(--mud-palette-error) !important}.mud-theme-error{color:var(--mud-paleLine truncated
|
||||||
+183
-182
@@ -1,43 +1,141 @@
|
|||||||
|
|
||||||
|
class MudKeyInterceptorFactory{connect(dotNetRef,elementId,options){if(!elementId)
|
||||||
|
throw"elementId: expected element id!";var element=document.getElementById(elementId);if(!element)
|
||||||
|
throw"no element found for id: "+elementId;if(!element.mudKeyInterceptor)
|
||||||
|
element.mudKeyInterceptor=new MudKeyInterceptor(dotNetRef,options);element.mudKeyInterceptor.connect(element);}
|
||||||
|
updatekey(elementId,option){var element=document.getElementById(elementId);if(!element||!element.mudKeyInterceptor)
|
||||||
|
return;element.mudKeyInterceptor.updatekey(option);}
|
||||||
|
disconnect(elementId){var element=document.getElementById(elementId);if(!element||!element.mudKeyInterceptor)
|
||||||
|
return;element.mudKeyInterceptor.disconnect();}}
|
||||||
|
window.mudKeyInterceptor=new MudKeyInterceptorFactory();class MudKeyInterceptor{constructor(dotNetRef,options){this._dotNetRef=dotNetRef;this._options=options;this.logger=options.enableLogging?console.log:(message)=>{};this.logger('[MudBlazor | KeyInterceptor] Interceptor initialized',{options});}
|
||||||
|
connect(element){if(!this._options)
|
||||||
|
return;if(!this._options.keys)
|
||||||
|
throw"_options.keys: array of KeyOptions expected";if(!this._options.targetClass)
|
||||||
|
throw"_options.targetClass: css class name expected";if(this._observer){return;}
|
||||||
|
var targetClass=this._options.targetClass;this.logger('[MudBlazor | KeyInterceptor] Start observing DOM of element for changes to child with class ',{element,targetClass});this._element=element;this._observer=new MutationObserver(this.onDomChanged);this._observer.mudKeyInterceptor=this;this._observer.observe(this._element,{attributes:false,childList:true,subtree:true});this._observedChildren=[];this._keyOptions={};this._regexOptions=[];for(const keyOption of this._options.keys){if(!keyOption||!keyOption.key){this.logger('[MudBlazor | KeyInterceptor] got invalid key options: ',keyOption);continue;}
|
||||||
|
this.setKeyOption(keyOption)}
|
||||||
|
this.logger('[MudBlazor | KeyInterceptor] key options: ',this._keyOptions);if(this._regexOptions.size>0)
|
||||||
|
this.logger('[MudBlazor | KeyInterceptor] regex options: ',this._regexOptions);for(const child of this._element.getElementsByClassName(targetClass)){this.attachHandlers(child);}}
|
||||||
|
setKeyOption(keyOption){if(keyOption.key.length>2&&keyOption.key.startsWith('/')&&keyOption.key.endsWith('/')){keyOption.regex=new RegExp(keyOption.key.substring(1,keyOption.key.length-1));this._regexOptions.push(keyOption);}
|
||||||
|
else
|
||||||
|
this._keyOptions[keyOption.key.toLowerCase()]=keyOption;var whitespace=new RegExp("\\s","g");keyOption.preventDown=(keyOption.preventDown||"none").replace(whitespace,"").toLowerCase();keyOption.preventUp=(keyOption.preventUp||"none").replace(whitespace,"").toLowerCase();keyOption.stopDown=(keyOption.stopDown||"none").replace(whitespace,"").toLowerCase();keyOption.stopUp=(keyOption.stopUp||"none").replace(whitespace,"").toLowerCase();}
|
||||||
|
updatekey(updatedOption){var option=this._keyOptions[updatedOption.key.toLowerCase()];option||this.logger('[MudBlazor | KeyInterceptor] updating option failed: key not registered');this.setKeyOption(updatedOption);this.logger('[MudBlazor | KeyInterceptor] updated option ',{option,updatedOption});}
|
||||||
|
disconnect(){if(!this._observer)
|
||||||
|
return;this.logger('[MudBlazor | KeyInterceptor] disconnect mutation observer and event handlers');this._observer.disconnect();this._observer=null;for(const child of this._observedChildren)
|
||||||
|
this.detachHandlers(child);}
|
||||||
|
attachHandlers(child){this.logger('[MudBlazor | KeyInterceptor] attaching handlers ',{child});if(this._observedChildren.indexOf(child)>-1){return;}
|
||||||
|
child.mudKeyInterceptor=this;child.addEventListener('keydown',this.onKeyDown);child.addEventListener('keyup',this.onKeyUp);this._observedChildren.push(child);}
|
||||||
|
detachHandlers(child){this.logger('[MudBlazor | KeyInterceptor] detaching handlers ',{child});child.removeEventListener('keydown',this.onKeyDown);child.removeEventListener('keyup',this.onKeyUp);this._observedChildren=this._observedChildren.filter(x=>x!==child);}
|
||||||
|
onDomChanged(mutationsList,observer){var self=this.mudKeyInterceptor;var targetClass=self._options.targetClass;for(const mutation of mutationsList){for(const element of mutation.addedNodes){if(element.classList&&element.classList.contains(targetClass))
|
||||||
|
self.attachHandlers(element);}
|
||||||
|
for(const element of mutation.removedNodes){if(element.classList&&element.classList.contains(targetClass))
|
||||||
|
self.detachHandlers(element);}}}
|
||||||
|
matchesKeyCombination(option,args){if(!option||option==="none")
|
||||||
|
return false;if(option==="any")
|
||||||
|
return true;var shift=args.shiftKey;var ctrl=args.ctrlKey;var alt=args.altKey;var meta=args.metaKey;var any=shift||ctrl||alt||meta;if(any&&option==="key+any")
|
||||||
|
return true;if(!any&&option.includes("key+none"))
|
||||||
|
return true;if(!any)
|
||||||
|
return false;var combi=`key${shift?"+shift":""}${ctrl?"+ctrl":""}${alt?"+alt":""}${meta?"+meta":""}`;return option.includes(combi);}
|
||||||
|
onKeyDown(args){var self=this.mudKeyInterceptor;var key=args.key.toLowerCase();self.logger('[MudBlazor | KeyInterceptor] down "'+key+'"',args);var invoke=false;if(self._keyOptions.hasOwnProperty(key)){var keyOptions=self._keyOptions[key];self.logger('[MudBlazor | KeyInterceptor] options for "'+key+'"',keyOptions);self.processKeyDown(args,keyOptions);if(keyOptions.subscribeDown)
|
||||||
|
invoke=true;}
|
||||||
|
for(const keyOptions of self._regexOptions){if(keyOptions.regex.test(key)){self.logger('[MudBlazor | KeyInterceptor] regex options for "'+key+'"',keyOptions);self.processKeyDown(args,keyOptions);if(keyOptions.subscribeDown)
|
||||||
|
invoke=true;}}
|
||||||
|
if(invoke){var eventArgs=self.toKeyboardEventArgs(args);eventArgs.Type="keydown";self._dotNetRef.invokeMethodAsync('OnKeyDown',self._element.id,eventArgs);}}
|
||||||
|
processKeyDown(args,keyOptions){if(this.matchesKeyCombination(keyOptions.preventDown,args))
|
||||||
|
args.preventDefault();if(this.matchesKeyCombination(keyOptions.stopDown,args))
|
||||||
|
args.stopPropagation();}
|
||||||
|
onKeyUp(args){var self=this.mudKeyInterceptor;var key=args.key.toLowerCase();self.logger('[MudBlazor | KeyInterceptor] up "'+key+'"',args);var invoke=false;if(self._keyOptions.hasOwnProperty(key)){var keyOptions=self._keyOptions[key];self.processKeyUp(args,keyOptions);if(keyOptions.subscribeUp)
|
||||||
|
invoke=true;}
|
||||||
|
for(const keyOptions of self._regexOptions){if(keyOptions.regex.test(key)){self.processKeyUp(args,keyOptions);if(keyOptions.subscribeUp)
|
||||||
|
invoke=true;}}
|
||||||
|
if(invoke){var eventArgs=self.toKeyboardEventArgs(args);eventArgs.Type="keyup";self._dotNetRef.invokeMethodAsync('OnKeyUp',self._element.id,eventArgs);}}
|
||||||
|
processKeyUp(args,keyOptions){if(this.matchesKeyCombination(keyOptions.preventUp,args))
|
||||||
|
args.preventDefault();if(this.matchesKeyCombination(keyOptions.stopUp,args))
|
||||||
|
args.stopPropagation();}
|
||||||
|
toKeyboardEventArgs(args){return{Key:args.key,Code:args.code,Location:args.location,Repeat:args.repeat,CtrlKey:args.ctrlKey,ShiftKey:args.shiftKey,AltKey:args.altKey,MetaKey:args.metaKey};}}
|
||||||
class MudInput{resetValue(id){const input=document.getElementById(id);if(input){input.value='';}}}
|
class MudInput{resetValue(id){const input=document.getElementById(id);if(input){input.value='';}}}
|
||||||
window.mudInput=new MudInput();window.mudInputAutoGrow={initAutoGrow:(elem,maxLines)=>{const compStyle=getComputedStyle(elem);const lineHeight=parseFloat(compStyle.getPropertyValue('line-height'));let maxHeight=0;elem.updateParameters=function(newMaxLines){if(newMaxLines>0){maxHeight=lineHeight*newMaxLines;}else{maxHeight=0;}}
|
window.mudInput=new MudInput();window.mudpopoverHelper={calculatePopoverPosition:function(list,boundingRect,selfRect){let top=0;let left=0;if(list.indexOf('mud-popover-anchor-top-left')>=0){left=boundingRect.left;top=boundingRect.top;}else if(list.indexOf('mud-popover-anchor-top-center')>=0){left=boundingRect.left+boundingRect.width/2;top=boundingRect.top;}else if(list.indexOf('mud-popover-anchor-top-right')>=0){left=boundingRect.left+boundingRect.width;top=boundingRect.top;}else if(list.indexOf('mud-popover-anchor-center-left')>=0){left=boundingRect.left;top=boundingRect.top+boundingRect.height/2;}else if(list.indexOf('mud-popover-anchor-center-center')>=0){left=boundingRect.left+boundingRect.width/2;top=boundingRect.top+boundingRect.height/2;}else if(list.indexOf('mud-popover-anchor-center-right')>=0){left=boundingRect.left+boundingRect.width;top=boundingRect.top+boundingRect.height/2;}else if(list.indexOf('mud-popover-anchor-bottom-left')>=0){left=boundingRect.left;top=boundingRect.top+boundingRect.height;}else if(list.indexOf('mud-popover-anchor-bottom-center')>=0){left=boundingRect.left+boundingRect.width/2;top=boundingRect.top+boundingRect.height;}else if(list.indexOf('mud-popover-anchor-bottom-right')>=0){left=boundingRect.left+boundingRect.width;top=boundingRect.top+boundingRect.height;}
|
||||||
elem.adjustAutoGrowHeight=function(didReflow=false){const scrollTops=[];let curElem=elem;while(curElem&&curElem.parentNode&&curElem.parentNode instanceof Element){if(curElem.parentNode.scrollTop){scrollTops.push([curElem.parentNode,curElem.parentNode.scrollTop]);}
|
let offsetX=0;let offsetY=0;if(list.indexOf('mud-popover-top-left')>=0){offsetX=0;offsetY=0;}else if(list.indexOf('mud-popover-top-center')>=0){offsetX=-selfRect.width/2;offsetY=0;}else if(list.indexOf('mud-popover-top-right')>=0){offsetX=-selfRect.width;offsetY=0;}
|
||||||
curElem=curElem.parentNode;}
|
else if(list.indexOf('mud-popover-center-left')>=0){offsetX=0;offsetY=-selfRect.height/2;}else if(list.indexOf('mud-popover-center-center')>=0){offsetX=-selfRect.width/2;offsetY=-selfRect.height/2;}else if(list.indexOf('mud-popover-center-right')>=0){offsetX=-selfRect.width;offsetY=-selfRect.height/2;}
|
||||||
elem.style.height=0;if(didReflow){elem.style.textAlign=null;}
|
else if(list.indexOf('mud-popover-bottom-left')>=0){offsetX=0;offsetY=-selfRect.height;}else if(list.indexOf('mud-popover-bottom-center')>=0){offsetX=-selfRect.width/2;offsetY=-selfRect.height;}else if(list.indexOf('mud-popover-bottom-right')>=0){offsetX=-selfRect.width;offsetY=-selfRect.height;}
|
||||||
let minHeight=lineHeight*elem.rows;let newHeight=Math.max(minHeight,elem.scrollHeight);let initialOverflowY=elem.style.overflowY;if(maxHeight>0&&newHeight>maxHeight){elem.style.overflowY='auto';newHeight=maxHeight;}else{elem.style.overflowY='hidden';}
|
return{top:top,left:left,offsetX:offsetX,offsetY:offsetY};},flipClassReplacements:{'top':{'mud-popover-top-left':'mud-popover-bottom-left','mud-popover-top-center':'mud-popover-bottom-center','mud-popover-anchor-bottom-center':'mud-popover-anchor-top-center','mud-popover-top-right':'mud-popover-bottom-right',},'left':{'mud-popover-top-left':'mud-popover-top-right','mud-popover-center-left':'mud-popover-center-right','mud-popover-anchor-center-right':'mud-popover-anchor-center-left','mud-popover-bottom-left':'mud-popover-bottom-right',},'right':{'mud-popover-top-right':'mud-popover-top-left','mud-popover-center-right':'mud-popover-center-left','mud-popover-anchor-center-left':'mud-popover-anchor-center-right','mud-popover-bottom-right':'mud-popover-bottom-left',},'bottom':{'mud-popover-bottom-left':'mud-popover-top-left','mud-popover-bottom-center':'mud-popover-top-center','mud-popover-anchor-top-center':'mud-popover-anchor-bottom-center','mud-popover-bottom-right':'mud-popover-top-right',},'top-and-left':{'mud-popover-top-left':'mud-popover-bottom-right',},'top-and-right':{'mud-popover-top-right':'mud-popover-bottom-left',},'bottom-and-left':{'mud-popover-bottom-left':'mud-popover-top-right',},'bottom-and-right':{'mud-popover-bottom-right':'mud-popover-top-left',},},flipMargin:0,getPositionForFlippedPopver:function(inputArray,selector,boundingRect,selfRect){const classList=[];for(var i=0;i<inputArray.length;i++){const item=inputArray[i];const replacments=window.mudpopoverHelper.flipClassReplacements[selector][item];if(replacments){classList.push(replacments);}
|
||||||
elem.style.height=newHeight+"px";scrollTops.forEach(([node,scrollTop])=>{node.style.scrollBehavior='auto';node.scrollTop=scrollTop;node.style.scrollBehavior=null;});if(!didReflow&&initialOverflowY!==elem.style.overflowY&&elem.style.overflowY==='hidden'){elem.style.textAlign='end';elem.adjustAutoGrowHeight(true);}}
|
else{classList.push(item);}}
|
||||||
elem.restoreToInitialState=function(){elem.removeEventListener('input',elem.adjustAutoGrowHeight);elem.style.overflowY=null;elem.style.height=null;}
|
return window.mudpopoverHelper.calculatePopoverPosition(classList,boundingRect,selfRect);},placePopover:function(popoverNode,classSelector){if(popoverNode&&popoverNode.parentNode){const id=popoverNode.id.substr(8);const popoverContentNode=document.getElementById('popovercontent-'+id);if(!popoverContentNode){return;}
|
||||||
elem.addEventListener('input',elem.adjustAutoGrowHeight);window.addEventListener('resize',elem.adjustAutoGrowHeight);elem.updateParameters(maxLines);elem.adjustAutoGrowHeight();},adjustHeight:(elem)=>{if(typeof elem.adjustAutoGrowHeight==='function'){elem.adjustAutoGrowHeight();}},updateParams:(elem,maxLines)=>{if(typeof elem.updateParameters==='function'){elem.updateParameters(maxLines);}
|
if(popoverContentNode.classList.contains('mud-popover-open')==false){return;}
|
||||||
if(typeof elem.adjustAutoGrowHeight==='function'){elem.adjustAutoGrowHeight();}},destroy:(elem)=>{if(elem==null){return;}
|
if(classSelector){if(popoverContentNode.classList.contains(classSelector)==false){return;}}
|
||||||
window.removeEventListener('resize',elem.adjustAutoGrowHeight);if(typeof elem.restoreToInitialState==='function'){elem.restoreToInitialState();}}};class MudFileUpload{openFilePicker(id){const element=document.getElementById(id);if(!element){return;}
|
const boundingRect=popoverNode.parentNode.getBoundingClientRect();if(popoverContentNode.classList.contains('mud-popover-relative-width')){popoverContentNode.style['max-width']=(boundingRect.width)+'px';}
|
||||||
try{element.showPicker();}catch(error){element.click();}}}
|
const selfRect=popoverContentNode.getBoundingClientRect();const classList=popoverContentNode.classList;const classListArray=Array.from(popoverContentNode.classList);const postion=window.mudpopoverHelper.calculatePopoverPosition(classListArray,boundingRect,selfRect);let left=postion.left;let top=postion.top;let offsetX=postion.offsetX;let offsetY=postion.offsetY;if(classList.contains('mud-popover-overflow-flip-onopen')||classList.contains('mud-popover-overflow-flip-always')){const appBarElements=document.getElementsByClassName("mud-appbar mud-appbar-fixed-top");let appBarOffset=0;if(appBarElements.length>0){appBarOffset=appBarElements[0].getBoundingClientRect().height;}
|
||||||
window.mudFileUpload=new MudFileUpload();class MudResizeObserverFactory{constructor(){this._maps={};}
|
const graceMargin=window.mudpopoverHelper.flipMargin;const deltaToLeft=left+offsetX;const deltaToRight=window.innerWidth-left-selfRect.width;const deltaTop=top-selfRect.height-appBarOffset;const spaceToTop=top-appBarOffset;const deltaBottom=window.innerHeight-top-selfRect.height;let selector=popoverContentNode.mudPopoverFliped;if(!selector){if(classList.contains('mud-popover-top-left')){if(deltaBottom<graceMargin&&deltaToRight<graceMargin&&spaceToTop>=selfRect.height&&deltaToLeft>=selfRect.width){selector='top-and-left';}else if(deltaBottom<graceMargin&&spaceToTop>=selfRect.height){selector='top';}else if(deltaToRight<graceMargin&&deltaToLeft>=selfRect.width){selector='left';}}else if(classList.contains('mud-popover-top-center')){if(deltaBottom<graceMargin&&spaceToTop>=selfRect.height){selector='top';}}else if(classList.contains('mud-popover-top-right')){if(deltaBottom<graceMargin&&deltaToLeft<graceMargin&&spaceToTop>=selfRect.height&&deltaToRight>=selfRect.width){selector='top-and-right';}else if(deltaBottom<graceMargin&&spaceToTop>=selfRect.height){selector='top';}else if(deltaToLeft<graceMargin&&deltaToRight>=selfRect.width){selector='right';}}
|
||||||
connect(id,dotNetRef,elements,elementIds,options){var existingEntry=this._maps[id];if(!existingEntry){var observer=new MudResizeObserver(dotNetRef,options);this._maps[id]=observer;}
|
else if(classList.contains('mud-popover-center-left')){if(deltaToRight<graceMargin&&deltaToLeft>=selfRect.width){selector='left';}}
|
||||||
var result=this._maps[id].connect(elements,elementIds);return result;}
|
else if(classList.contains('mud-popover-center-right')){if(deltaToLeft<graceMargin&&deltaToRight>=selfRect.width){selector='right';}}
|
||||||
disconnect(id,element){var existingEntry=this._maps[id];if(existingEntry){existingEntry.disconnect(element);}}
|
else if(classList.contains('mud-popover-bottom-left')){if(deltaTop<graceMargin&&deltaToRight<graceMargin&&deltaBottom>=0&&deltaToLeft>=selfRect.width){selector='bottom-and-left';}else if(deltaTop<graceMargin&&deltaBottom>=0){selector='bottom';}else if(deltaToRight<graceMargin&&deltaToLeft>=selfRect.width){selector='left';}}else if(classList.contains('mud-popover-bottom-center')){if(deltaTop<graceMargin&&deltaBottom>=0){selector='bottom';}}else if(classList.contains('mud-popover-bottom-right')){if(deltaTop<graceMargin&&deltaToLeft<graceMargin&&deltaBottom>=0&&deltaToRight>=selfRect.width){selector='bottom-and-right';}else if(deltaTop<graceMargin&&deltaBottom>=0){selector='bottom';}else if(deltaToLeft<graceMargin&&deltaToRight>=selfRect.width){selector='right';}}}
|
||||||
cancelListener(id){var existingEntry=this._maps[id];if(existingEntry){existingEntry.cancelListener();delete this._maps[id];}}}
|
if(selector&&selector!='none'){const newPosition=window.mudpopoverHelper.getPositionForFlippedPopver(classListArray,selector,boundingRect,selfRect);left=newPosition.left;top=newPosition.top;offsetX=newPosition.offsetX;offsetY=newPosition.offsetY;popoverContentNode.setAttribute('data-mudpopover-flip','flipped');}
|
||||||
class MudResizeObserver{constructor(dotNetRef,options){this.logger=options.enableLogging?console.log:(message)=>{};this.options=options;this._dotNetRef=dotNetRef
|
else{if(left+offsetX<0){left=Math.max(0,left+offsetX);offsetX=0;}
|
||||||
var delay=(this.options||{}).reportRate||200;this.throttleResizeHandlerId=-1;var observervedElements=[];this._observervedElements=observervedElements;this.logger('[MudBlazor | ResizeObserver] Observer initialized');this._resizeObserver=new ResizeObserver(entries=>{var changes=[];this.logger('[MudBlazor | ResizeObserver] changes detected');for(let entry of entries){var target=entry.target;var affectedObservedElement=observervedElements.find((x)=>x.element==target);if(affectedObservedElement){var size=entry.target.getBoundingClientRect();if(affectedObservedElement.isInitialized==true){changes.push({id:affectedObservedElement.id,size:size});}
|
if(top+offsetY<appBarOffset){top=Math.max(appBarOffset,top+offsetY);offsetY=0;}
|
||||||
else{affectedObservedElement.isInitialized=true;}}}
|
popoverContentNode.removeAttribute('data-mudpopover-flip');}
|
||||||
if(changes.length>0){if(this.throttleResizeHandlerId>=0){clearTimeout(this.throttleResizeHandlerId);}
|
if(classList.contains('mud-popover-overflow-flip-onopen')){if(!popoverContentNode.mudPopoverFliped){popoverContentNode.mudPopoverFliped=selector||'none';}}}
|
||||||
this.throttleResizeHandlerId=window.setTimeout(this.resizeHandler.bind(this,changes),delay);}});}
|
if(popoverContentNode.classList.contains('mud-popover-fixed')){}
|
||||||
resizeHandler(changes){try{this.logger("[MudBlazor | ResizeObserver] OnSizeChanged handler invoked");this._dotNetRef.invokeMethodAsync("OnSizeChanged",changes);}catch(error){this.logger("[MudBlazor | ResizeObserver] Error in OnSizeChanged handler:",{error});}}
|
else if(window.getComputedStyle(popoverNode).position=='fixed'){popoverContentNode.style['position']='fixed';}
|
||||||
connect(elements,ids){var result=[];this.logger('[MudBlazor | ResizeObserver] Start observing elements...');for(var i=0;i<elements.length;i++){var newEntry={element:elements[i],id:ids[i],isInitialized:false,};this.logger("[MudBlazor | ResizeObserver] Start observing element:",{newEntry});result.push(elements[i].getBoundingClientRect());this._observervedElements.push(newEntry);this._resizeObserver.observe(elements[i]);}
|
else{offsetX+=window.scrollX;offsetY+=window.scrollY}
|
||||||
return result;}
|
popoverContentNode.style['left']=(left+offsetX)+'px';popoverContentNode.style['top']=(top+offsetY)+'px';if(window.getComputedStyle(popoverNode).getPropertyValue('z-index')!='auto'){popoverContentNode.style['z-index']=window.getComputedStyle(popoverNode).getPropertyValue('z-index');popoverContentNode.skipZIndex=true;}}},placePopoverByClassSelector:function(classSelector=null){var items=window.mudPopover.getAllObservedContainers();for(let i=0;i<items.length;i++){const popoverNode=document.getElementById('popover-'+items[i]);window.mudpopoverHelper.placePopover(popoverNode,classSelector);}},placePopoverByNode:function(target){const id=target.id.substr(15);const popoverNode=document.getElementById('popover-'+id);window.mudpopoverHelper.placePopover(popoverNode);},countProviders:function(){return document.querySelectorAll(".mud-popover-provider").length;}}
|
||||||
disconnect(elementId){this.logger('[MudBlazor | ResizeObserver] Try to unobserve element with id',{elementId});var affectedObservedElement=this._observervedElements.find((x)=>x.id==elementId);if(affectedObservedElement){var element=affectedObservedElement.element;this._resizeObserver.unobserve(element);this.logger('[MudBlazor | ResizeObserver] Element found. Ubobserving size changes of element',{element});var index=this._observervedElements.indexOf(affectedObservedElement);this._observervedElements.splice(index,1);}}
|
class MudPopover{constructor(){this.map={};this.contentObserver=null;this.mainContainerClass=null;}
|
||||||
cancelListener(){this.logger('[MudBlazor | ResizeObserver] Closing ResizeObserver. Detaching all observed elements');this._resizeObserver.disconnect();this._dotNetRef=undefined;}}
|
callback(id,mutationsList,observer){for(const mutation of mutationsList){if(mutation.type==='attributes'){const target=mutation.target
|
||||||
window.mudResizeObserver=new MudResizeObserverFactory();class MudWindow{copyToClipboard(text){navigator.clipboard.writeText(text);}
|
if(mutation.attributeName=='class'){if(target.classList.contains('mud-popover-overflow-flip-onopen')&&target.classList.contains('mud-popover-open')==false){target.mudPopoverFliped=null;target.removeAttribute('data-mudpopover-flip');}
|
||||||
changeCssById(id,css){var element=document.getElementById(id);if(element){element.className=css;}}
|
window.mudpopoverHelper.placePopoverByNode(target);}
|
||||||
updateStyleProperty(elementId,propertyName,value){const element=document.getElementById(elementId);if(element){element.style.setProperty(propertyName,value);}}
|
else if(mutation.attributeName=='data-ticks'){const tickAttribute=target.getAttribute('data-ticks');const parent=target.parentElement;const tickValues=[];let max=-1;if(parent){for(let i=0;i<parent.children.length;i++){const childNode=parent.children[i];const tickValue=parseInt(childNode.getAttribute('data-ticks'));if(tickValue==0){continue;}
|
||||||
changeGlobalCssVariable(name,newValue){document.documentElement.style.setProperty(name,newValue);}
|
if(tickValues.indexOf(tickValue)>=0){continue;}
|
||||||
open(args){window.open(args);}}
|
tickValues.push(tickValue);if(tickValue>max){max=tickValue;}}}
|
||||||
window.mudWindow=new MudWindow();window.mudTimePicker={initPointerEvents:(clock,dotNetHelper)=>{let isPointerDown=false;const startHandler=(event)=>{if(event.button!==0){return;}
|
if(tickValues.length==0){continue;}
|
||||||
|
const sortedTickValues=tickValues.sort((x,y)=>x-y);for(let i=0;i<parent.children.length;i++){const childNode=parent.children[i];const tickValue=parseInt(childNode.getAttribute('data-ticks'));if(tickValue==0){continue;}
|
||||||
|
if(childNode.skipZIndex==true){continue;}
|
||||||
|
childNode.style['z-index']='calc(var(--mud-zindex-popover) + '+(sortedTickValues.indexOf(tickValue)+3).toString()+')';}}}}}
|
||||||
|
initialize(containerClass,flipMargin){const mainContent=document.getElementsByClassName(containerClass);if(mainContent.length==0){return;}
|
||||||
|
if(flipMargin){window.mudpopoverHelper.flipMargin=flipMargin;}
|
||||||
|
this.mainContainerClass=containerClass;if(!mainContent[0].mudPopoverMark){mainContent[0].mudPopoverMark="mudded";if(this.contentObserver!=null){this.contentObserver.disconnect();this.contentObserver=null;}
|
||||||
|
this.contentObserver=new ResizeObserver(entries=>{window.mudpopoverHelper.placePopoverByClassSelector();});this.contentObserver.observe(mainContent[0]);}}
|
||||||
|
connect(id){this.initialize(this.mainContainerClass);const popoverNode=document.getElementById('popover-'+id);const popoverContentNode=document.getElementById('popovercontent-'+id);if(popoverNode&&popoverNode.parentNode&&popoverContentNode){window.mudpopoverHelper.placePopover(popoverNode);const config={attributeFilter:['class','data-ticks']};const observer=new MutationObserver(this.callback.bind(this,id));observer.observe(popoverContentNode,config);const resizeObserver=new ResizeObserver(entries=>{for(let entry of entries){const target=entry.target;for(var i=0;i<target.childNodes.length;i++){const childNode=target.childNodes[i];if(childNode.id&&childNode.id.startsWith('popover-')){window.mudpopoverHelper.placePopover(childNode);}}}});resizeObserver.observe(popoverNode.parentNode);const contentNodeObserver=new ResizeObserver(entries=>{for(let entry of entries){var target=entry.target;window.mudpopoverHelper.placePopoverByNode(target);}});contentNodeObserver.observe(popoverContentNode);this.map[id]={mutationObserver:observer,resizeObserver:resizeObserver,contentNodeObserver:contentNodeObserver};}}
|
||||||
|
disconnect(id){if(this.map[id]){const item=this.map[id]
|
||||||
|
item.mutationObserver.disconnect();item.resizeObserver.disconnect();item.contentNodeObserver.disconnect();delete this.map[id];}}
|
||||||
|
dispose(){for(var i in this.map){disconnect(i);}
|
||||||
|
this.contentObserver.disconnect();this.contentObserver=null;}
|
||||||
|
getAllObservedContainers(){const result=[];for(var i in this.map){result.push(i);}
|
||||||
|
return result;}}
|
||||||
|
window.mudPopover=new MudPopover();window.addEventListener('scroll',()=>{window.mudpopoverHelper.placePopoverByClassSelector('mud-popover-fixed');window.mudpopoverHelper.placePopoverByClassSelector('mud-popover-overflow-flip-always');});window.addEventListener('resize',()=>{window.mudpopoverHelper.placePopoverByClassSelector();});window.mudTimePicker={initPointerEvents:(clock,dotNetHelper)=>{let isPointerDown=false;const startHandler=(event)=>{if(event.button!==0){return;}
|
||||||
isPointerDown=true;event.target.releasePointerCapture(event.pointerId);if(event.target.classList.contains('mud-hour')||event.target.classList.contains('mud-minute')){let attributeValue=event.target.getAttribute('data-stick-value');let stickValue=attributeValue?parseInt(attributeValue):-1;dotNetHelper.invokeMethodAsync('SelectTimeFromStick',stickValue,false);}
|
isPointerDown=true;event.target.releasePointerCapture(event.pointerId);if(event.target.classList.contains('mud-hour')||event.target.classList.contains('mud-minute')){let attributeValue=event.target.getAttribute('data-stick-value');let stickValue=attributeValue?parseInt(attributeValue):-1;dotNetHelper.invokeMethodAsync('SelectTimeFromStick',stickValue,false);}
|
||||||
event.preventDefault();};const endHandler=(event)=>{if(event.button!==0){return;}
|
event.preventDefault();};const endHandler=(event)=>{if(event.button!==0){return;}
|
||||||
isPointerDown=false;if(event.target.classList.contains('mud-hour')||event.target.classList.contains('mud-minute')){let attributeValue=event.target.getAttribute('data-stick-value');let stickValue=attributeValue?parseInt(attributeValue):-1;dotNetHelper.invokeMethodAsync('OnStickClick',stickValue);}
|
isPointerDown=false;if(event.target.classList.contains('mud-hour')||event.target.classList.contains('mud-minute')){let attributeValue=event.target.getAttribute('data-stick-value');let stickValue=attributeValue?parseInt(attributeValue):-1;dotNetHelper.invokeMethodAsync('OnStickClick',stickValue);}
|
||||||
event.preventDefault();};const moveHandler=(event)=>{if(!isPointerDown||(!event.target.classList.contains('mud-hour')&&!event.target.classList.contains('mud-minute'))){return;}
|
event.preventDefault();};const moveHandler=(event)=>{if(!isPointerDown||(!event.target.classList.contains('mud-hour')&&!event.target.classList.contains('mud-minute'))){return;}
|
||||||
let attributeValue=event.target.getAttribute('data-stick-value');let stickValue=attributeValue?parseInt(attributeValue):-1;dotNetHelper.invokeMethodAsync('SelectTimeFromStick',stickValue,true);event.preventDefault();};clock.addEventListener('pointerdown',startHandler);clock.addEventListener('pointerup',endHandler);clock.addEventListener('pointercancel',endHandler);clock.addEventListener('pointerover',moveHandler);clock.destroy=()=>{clock.removeEventListener('pointerdown',startHandler);clock.removeEventListener('pointerup',endHandler);clock.removeEventListener('pointercancel',endHandler);clock.removeEventListener('pointerover',moveHandler);};},destroyPointerEvents:(container)=>{if(container==null){return;}
|
let attributeValue=event.target.getAttribute('data-stick-value');let stickValue=attributeValue?parseInt(attributeValue):-1;dotNetHelper.invokeMethodAsync('SelectTimeFromStick',stickValue,true);event.preventDefault();};clock.addEventListener('pointerdown',startHandler);clock.addEventListener('pointerup',endHandler);clock.addEventListener('pointercancel',endHandler);clock.addEventListener('pointerover',moveHandler);clock.destroy=()=>{clock.removeEventListener('pointerdown',startHandler);clock.removeEventListener('pointerup',endHandler);clock.removeEventListener('pointercancel',endHandler);clock.removeEventListener('pointerover',moveHandler);};},destroyPointerEvents:(container)=>{if(container==null){return;}
|
||||||
if(typeof container.destroy==='function'){container.destroy();}}};class MudJsEventFactory{connect(dotNetRef,elementId,options){if(!elementId)
|
if(typeof container.destroy==='function'){container.destroy();}}};class MudResizeListener{constructor(id){this.logger=function(message){};this.options={};this.throttleResizeHandlerId=-1;this.dotnet=undefined;this.breakpoint=-1;this.id=id;this.handleResize=this.throttleResizeHandler.bind(this);}
|
||||||
|
listenForResize(dotnetRef,options){if(this.dotnet){this.options=options;return;}
|
||||||
|
this.options=options;this.dotnet=dotnetRef;this.logger=options.enableLogging?console.log:(message)=>{};this.logger(`[MudBlazor]Reporting resize events at rate of:${this.options.reportRate}ms`);window.addEventListener("resize",this.handleResize,false);if(!this.options.suppressInitEvent){this.resizeHandler();}
|
||||||
|
this.breakpoint=this.getBreakpoint(window.innerWidth);}
|
||||||
|
throttleResizeHandler(){clearTimeout(this.throttleResizeHandlerId);this.throttleResizeHandlerId=window.setTimeout(this.resizeHandler.bind(this),this.options.reportRate);}
|
||||||
|
resizeHandler(){if(this.options.notifyOnBreakpointOnly){let bp=this.getBreakpoint(window.innerWidth);if(bp==this.breakpoint){return;}
|
||||||
|
this.breakpoint=bp;}
|
||||||
|
try{if(this.id){this.dotnet.invokeMethodAsync('RaiseOnResized',{height:window.innerHeight,width:window.innerWidth},this.getBreakpoint(window.innerWidth),this.id);}
|
||||||
|
else{this.dotnet.invokeMethodAsync('RaiseOnResized',{height:window.innerHeight,width:window.innerWidth},this.getBreakpoint(window.innerWidth));}}catch(error){this.logger("[MudBlazor] Error in resizeHandler:",{error});}}
|
||||||
|
cancelListener(){this.dotnet=undefined;window.removeEventListener("resize",this.handleResize);}
|
||||||
|
matchMedia(query){let m=window.matchMedia(query).matches;return m;}
|
||||||
|
getBrowserWindowSize(){return{height:window.innerHeight,width:window.innerWidth};}
|
||||||
|
getBreakpoint(width){if(width>=this.options.breakpointDefinitions["Xxl"])
|
||||||
|
return 5;else if(width>=this.options.breakpointDefinitions["Xl"])
|
||||||
|
return 4;else if(width>=this.options.breakpointDefinitions["Lg"])
|
||||||
|
return 3;else if(width>=this.options.breakpointDefinitions["Md"])
|
||||||
|
return 2;else if(width>=this.options.breakpointDefinitions["Sm"])
|
||||||
|
return 1;else
|
||||||
|
return 0;}};window.mudResizeListener=new MudResizeListener();window.mudResizeListenerFactory={mapping:{},listenForResize:(dotnetRef,options,id)=>{var map=window.mudResizeListenerFactory.mapping;if(map[id]){return;}
|
||||||
|
var listener=new MudResizeListener(id);listener.listenForResize(dotnetRef,options);map[id]=listener;},cancelListener:(id)=>{var map=window.mudResizeListenerFactory.mapping;if(!map[id]){return;}
|
||||||
|
var listener=map[id];listener.cancelListener();delete map[id];},cancelListeners:(ids)=>{for(let i=0;i<ids.length;i++){window.mudResizeListenerFactory.cancelListener(ids[i]);}},dispose(){var map=window.mudResizeListenerFactory.mapping;for(var id in map){window.mudResizeListenerFactory.cancelListener(id);}}}
|
||||||
|
class MudFileUpload{openFilePicker(id){const element=document.getElementById(id);if(!element){return;}
|
||||||
|
try{element.showPicker();}catch(error){element.click();}}}
|
||||||
|
window.mudFileUpload=new MudFileUpload();window.mudDragAndDrop={initDropZone:(id)=>{const elem=document.getElementById(id);elem.addEventListener('dragover',()=>event.preventDefault());elem.addEventListener('dragstart',()=>event.dataTransfer.setData('',event.target.id));},makeDropZonesNotRelative:()=>{var firstDropItems=Array.from(document.getElementsByClassName('mud-drop-item')).filter(x=>x.getAttribute('index')=="-1");for(let dropItem of firstDropItems){dropItem.style.position='static';}
|
||||||
|
const dropZones=document.getElementsByClassName('mud-drop-zone');for(let dropZone of dropZones){dropZone.style.position='unset';}},getDropZoneIdentifierOnPosition:(x,y)=>{const elems=document.elementsFromPoint(x,y);const dropZones=elems.filter(e=>e.classList.contains('mud-drop-zone'))
|
||||||
|
const dropZone=dropZones[0];if(dropZone){return dropZone.getAttribute('identifier')||"";}
|
||||||
|
return"";},getDropIndexOnPosition:(x,y,id)=>{const elems=document.elementsFromPoint(x,y);const dropItems=elems.filter(e=>e.classList.contains('mud-drop-item')&&e.id!=id)
|
||||||
|
const dropItem=dropItems[0];if(dropItem){return dropItem.getAttribute('index')||"";}
|
||||||
|
return"";},makeDropZonesRelative:()=>{const dropZones=document.getElementsByClassName('mud-drop-zone');for(let dropZone of dropZones){dropZone.style.position='relative';}
|
||||||
|
var firstDropItems=Array.from(document.getElementsByClassName('mud-drop-item')).filter(x=>x.getAttribute('index')=="-1");for(let dropItem of firstDropItems){dropItem.style.position='relative';}},moveItemByDifference:(id,dx,dy)=>{const elem=document.getElementById(id);var tx=(parseFloat(elem.getAttribute('data-x'))||0)+dx;var ty=(parseFloat(elem.getAttribute('data-y'))||0)+dy;elem.style.webkitTransform=elem.style.transform='translate3d('+tx+'px, '+ty+'px, 10px)';elem.setAttribute('data-x',tx);elem.setAttribute('data-y',ty);},resetItem:(id)=>{const elem=document.getElementById(id);if(elem){elem.style.webkitTransform=elem.style.transform='';elem.setAttribute('data-x',0);elem.setAttribute('data-y',0);}}};class MudJsEventFactory{connect(dotNetRef,elementId,options){if(!elementId)
|
||||||
throw"[MudBlazor | JsEvent] elementId: expected element id!";var element=document.getElementById(elementId);if(!element)
|
throw"[MudBlazor | JsEvent] elementId: expected element id!";var element=document.getElementById(elementId);if(!element)
|
||||||
throw"[MudBlazor | JsEvent] no element found for id: "+elementId;if(!element.mudJsEvent)
|
throw"[MudBlazor | JsEvent] no element found for id: "+elementId;if(!element.mudJsEvent)
|
||||||
element.mudJsEvent=new MudJsEvent(dotNetRef,options);element.mudJsEvent.connect(element);}
|
element.mudJsEvent=new MudJsEvent(dotNetRef,options);element.mudJsEvent.connect(element);}
|
||||||
@@ -80,40 +178,38 @@ onclick(self,e){const caretPosition=e.target.selectionStart;const invoke=self._s
|
|||||||
onpaste(self,e){const invoke=self._subscribedEvents["paste"];if(invoke){e.preventDefault();e.stopPropagation();const text=(e.originalEvent||e).clipboardData.getData('text/plain');self._dotNetRef.invokeMethodAsync('OnPaste',text);}}
|
onpaste(self,e){const invoke=self._subscribedEvents["paste"];if(invoke){e.preventDefault();e.stopPropagation();const text=(e.originalEvent||e).clipboardData.getData('text/plain');self._dotNetRef.invokeMethodAsync('OnPaste',text);}}
|
||||||
onselect(self,e){const invoke=self._subscribedEvents["select"];if(invoke){const start=e.target.selectionStart;const end=e.target.selectionEnd;if(start===end)
|
onselect(self,e){const invoke=self._subscribedEvents["select"];if(invoke){const start=e.target.selectionStart;const end=e.target.selectionEnd;if(start===end)
|
||||||
return;self._dotNetRef.invokeMethodAsync('OnSelect',start,end);}}}
|
return;self._dotNetRef.invokeMethodAsync('OnSelect',start,end);}}}
|
||||||
window.getTabbableElements=(element)=>{return element.querySelectorAll("a[href]:not([tabindex='-1']),"+"area[href]:not([tabindex='-1']),"+"button:not([disabled]):not([tabindex='-1']),"+"input:not([disabled]):not([tabindex='-1']):not([type='hidden']),"+"select:not([disabled]):not([tabindex='-1']),"+"textarea:not([disabled]):not([tabindex='-1']),"+"iframe:not([tabindex='-1']),"+"details:not([tabindex='-1']),"+"[tabindex]:not([tabindex='-1']),"+"[contentEditable=true]:not([tabindex='-1'])");};window.serializeParameter=(data,spec)=>{if(typeof data=="undefined"||data===null){return null;}
|
class MudScrollManager{scrollToYear(elementId,offset){let element=document.getElementById(elementId);if(element){element.parentNode.scrollTop=element.offsetTop-element.parentNode.offsetTop-element.scrollHeight*3;}}
|
||||||
if(typeof data==="number"||typeof data==="string"||typeof data=="boolean"){return data;}
|
scrollToListItem(elementId){let element=document.getElementById(elementId);if(element){let parent=element.parentElement;if(parent){parent.scrollTop=element.offsetTop;}}}
|
||||||
let res=(Array.isArray(data))?[]:{};if(!spec){spec="*";}
|
scrollTo(selector,left,top,behavior){let element=document.querySelector(selector)||document.documentElement;element.scrollTo({left,top,behavior});}
|
||||||
for(let i in data){let currentMember=data[i];if(typeof currentMember==='function'||currentMember===null){continue;}
|
scrollIntoView(selector,behavior){let element=document.querySelector(selector)||document.documentElement;if(element)
|
||||||
let currentMemberSpec;if(spec!="*"){currentMemberSpec=Array.isArray(data)?spec:spec[i];if(!currentMemberSpec){continue;}}else{currentMemberSpec="*"}
|
element.scrollIntoView({behavior,block:'center',inline:'start'});}
|
||||||
if(typeof currentMember==='object'){if(Array.isArray(currentMember)||currentMember.length){res[i]=[];for(let j=0;j<currentMember.length;j++){const arrayItem=currentMember[j];if(typeof arrayItem==='object'){res[i].push(this.serializeParameter(arrayItem,currentMemberSpec));}else{res[i].push(arrayItem);}}}else{if(currentMember.length===0){res[i]=[];}else{res[i]=this.serializeParameter(currentMember,currentMemberSpec);}}}else{if(currentMember===Infinity){currentMember="Infinity";}
|
scrollToBottom(selector,behavior){let element=document.querySelector(selector);if(element){element.scrollTo({top:element.scrollHeight,behavior:behavior});}else{window.scrollTo({top:document.body.scrollHeight,behavior:behavior});}}
|
||||||
if(currentMember!==null){res[i]=currentMember;}}}
|
lockScroll(selector,lockclass){let element=document.querySelector(selector)||document.body;let hasScrollBar=window.innerWidth>document.body.clientWidth;if(hasScrollBar){element.classList.add(lockclass);}else{let lockClassNoPadding=lockclass+"-no-padding";element.classList.add(lockClassNoPadding);}}
|
||||||
return res;};function setRippleOffset(event,target){const rect=target.getBoundingClientRect();const x=event.clientX-rect.left-rect.width/2;const y=event.clientY-rect.top-rect.height/2;target.style.setProperty("--mud-ripple-offset-x",`${x}px`);target.style.setProperty("--mud-ripple-offset-y",`${y}px`);}
|
unlockScroll(selector,lockclass){let element=document.querySelector(selector)||document.body;element.classList.remove(lockclass);element.classList.remove(lockclass+"-no-padding");}};window.mudScrollManager=new MudScrollManager();window.mudInputAutoGrow={initAutoGrow:(elem,maxLines)=>{const compStyle=getComputedStyle(elem);const lineHeight=parseFloat(compStyle.getPropertyValue('line-height'));let maxHeight=0;elem.updateParameters=function(newMaxLines){if(newMaxLines>0){maxHeight=lineHeight*newMaxLines;}else{maxHeight=0;}}
|
||||||
document.addEventListener("click",function(event){const target=event.target.closest(".mud-ripple");if(target){setRippleOffset(event,target);}});class MudResizeListener{constructor(id){this.logger=function(message){};this.options={};this.throttleResizeHandlerId=-1;this.dotnet=undefined;this.breakpoint=-1;this.id=id;this.handleResize=this.throttleResizeHandler.bind(this);}
|
elem.adjustAutoGrowHeight=function(didReflow=false){const scrollTops=[];let curElem=elem;while(curElem&&curElem.parentNode&&curElem.parentNode instanceof Element){if(curElem.parentNode.scrollTop){scrollTops.push([curElem.parentNode,curElem.parentNode.scrollTop]);}
|
||||||
listenForResize(dotnetRef,options){if(this.dotnet){this.options=options;return;}
|
curElem=curElem.parentNode;}
|
||||||
this.options=options;this.dotnet=dotnetRef;this.logger=options.enableLogging?console.log:(message)=>{};this.logger(`[MudBlazor]Reporting resize events at rate of:${this.options.reportRate}ms`);window.addEventListener("resize",this.handleResize,false);if(!this.options.suppressInitEvent){this.resizeHandler();}
|
elem.style.height=0;if(didReflow){elem.style.textAlign=null;}
|
||||||
this.breakpoint=this.getBreakpoint(window.innerWidth);}
|
let minHeight=lineHeight*elem.rows;let newHeight=Math.max(minHeight,elem.scrollHeight);let initialOverflowY=elem.style.overflowY;if(maxHeight>0&&newHeight>maxHeight){elem.style.overflowY='auto';newHeight=maxHeight;}else{elem.style.overflowY='hidden';}
|
||||||
throttleResizeHandler(){clearTimeout(this.throttleResizeHandlerId);this.throttleResizeHandlerId=window.setTimeout(this.resizeHandler.bind(this),this.options.reportRate);}
|
elem.style.height=newHeight+"px";scrollTops.forEach(([node,scrollTop])=>{node.style.scrollBehavior='auto';node.scrollTop=scrollTop;node.style.scrollBehavior=null;});if(!didReflow&&initialOverflowY!==elem.style.overflowY&&elem.style.overflowY==='hidden'){elem.style.textAlign='end';elem.adjustAutoGrowHeight(true);}}
|
||||||
resizeHandler(){if(this.options.notifyOnBreakpointOnly){let bp=this.getBreakpoint(window.innerWidth);if(bp==this.breakpoint){return;}
|
elem.restoreToInitialState=function(){elem.removeEventListener('input',elem.adjustAutoGrowHeight);elem.style.overflowY=null;elem.style.height=null;}
|
||||||
this.breakpoint=bp;}
|
elem.addEventListener('input',elem.adjustAutoGrowHeight);window.addEventListener('resize',elem.adjustAutoGrowHeight);elem.updateParameters(maxLines);elem.adjustAutoGrowHeight();},adjustHeight:(elem)=>{if(typeof elem.adjustAutoGrowHeight==='function'){elem.adjustAutoGrowHeight();}},updateParams:(elem,maxLines)=>{if(typeof elem.updateParameters==='function'){elem.updateParameters(maxLines);}
|
||||||
try{if(this.id){this.dotnet.invokeMethodAsync('RaiseOnResized',{height:window.innerHeight,width:window.innerWidth},this.getBreakpoint(window.innerWidth),this.id);}
|
if(typeof elem.adjustAutoGrowHeight==='function'){elem.adjustAutoGrowHeight();}},destroy:(elem)=>{if(elem==null){return;}
|
||||||
else{this.dotnet.invokeMethodAsync('RaiseOnResized',{height:window.innerHeight,width:window.innerWidth},this.getBreakpoint(window.innerWidth));}}catch(error){this.logger("[MudBlazor] Error in resizeHandler:",{error});}}
|
window.removeEventListener('resize',elem.adjustAutoGrowHeight);if(typeof elem.restoreToInitialState==='function'){elem.restoreToInitialState();}}};class MudResizeObserverFactory{constructor(){this._maps={};}
|
||||||
cancelListener(){this.dotnet=undefined;window.removeEventListener("resize",this.handleResize);}
|
connect(id,dotNetRef,elements,elementIds,options){var existingEntry=this._maps[id];if(!existingEntry){var observer=new MudResizeObserver(dotNetRef,options);this._maps[id]=observer;}
|
||||||
matchMedia(query){let m=window.matchMedia(query).matches;return m;}
|
var result=this._maps[id].connect(elements,elementIds);return result;}
|
||||||
getBrowserWindowSize(){return{height:window.innerHeight,width:window.innerWidth};}
|
disconnect(id,element){var existingEntry=this._maps[id];if(existingEntry){existingEntry.disconnect(element);}}
|
||||||
getBreakpoint(width){if(width>=this.options.breakpointDefinitions["Xxl"])
|
cancelListener(id){var existingEntry=this._maps[id];if(existingEntry){existingEntry.cancelListener();delete this._maps[id];}}}
|
||||||
return 5;else if(width>=this.options.breakpointDefinitions["Xl"])
|
class MudResizeObserver{constructor(dotNetRef,options){this.logger=options.enableLogging?console.log:(message)=>{};this.options=options;this._dotNetRef=dotNetRef
|
||||||
return 4;else if(width>=this.options.breakpointDefinitions["Lg"])
|
var delay=(this.options||{}).reportRate||200;this.throttleResizeHandlerId=-1;var observervedElements=[];this._observervedElements=observervedElements;this.logger('[MudBlazor | ResizeObserver] Observer initialized');this._resizeObserver=new ResizeObserver(entries=>{var changes=[];this.logger('[MudBlazor | ResizeObserver] changes detected');for(let entry of entries){var target=entry.target;var affectedObservedElement=observervedElements.find((x)=>x.element==target);if(affectedObservedElement){var size=entry.target.getBoundingClientRect();if(affectedObservedElement.isInitialized==true){changes.push({id:affectedObservedElement.id,size:size});}
|
||||||
return 3;else if(width>=this.options.breakpointDefinitions["Md"])
|
else{affectedObservedElement.isInitialized=true;}}}
|
||||||
return 2;else if(width>=this.options.breakpointDefinitions["Sm"])
|
if(changes.length>0){if(this.throttleResizeHandlerId>=0){clearTimeout(this.throttleResizeHandlerId);}
|
||||||
return 1;else
|
this.throttleResizeHandlerId=window.setTimeout(this.resizeHandler.bind(this,changes),delay);}});}
|
||||||
return 0;}};window.mudResizeListener=new MudResizeListener();window.mudResizeListenerFactory={mapping:{},listenForResize:(dotnetRef,options,id)=>{var map=window.mudResizeListenerFactory.mapping;if(map[id]){return;}
|
resizeHandler(changes){try{this.logger("[MudBlazor | ResizeObserver] OnSizeChanged handler invoked");this._dotNetRef.invokeMethodAsync("OnSizeChanged",changes);}catch(error){this.logger("[MudBlazor | ResizeObserver] Error in OnSizeChanged handler:",{error});}}
|
||||||
var listener=new MudResizeListener(id);listener.listenForResize(dotnetRef,options);map[id]=listener;},cancelListener:(id)=>{var map=window.mudResizeListenerFactory.mapping;if(!map[id]){return;}
|
connect(elements,ids){var result=[];this.logger('[MudBlazor | ResizeObserver] Start observing elements...');for(var i=0;i<elements.length;i++){var newEntry={element:elements[i],id:ids[i],isInitialized:false,};this.logger("[MudBlazor | ResizeObserver] Start observing element:",{newEntry});result.push(elements[i].getBoundingClientRect());this._observervedElements.push(newEntry);this._resizeObserver.observe(elements[i]);}
|
||||||
var listener=map[id];listener.cancelListener();delete map[id];},cancelListeners:(ids)=>{for(let i=0;i<ids.length;i++){window.mudResizeListenerFactory.cancelListener(ids[i]);}},dispose(){var map=window.mudResizeListenerFactory.mapping;for(var id in map){window.mudResizeListenerFactory.cancelListener(id);}}}
|
return result;}
|
||||||
class MudScrollListener{constructor(){this.throttleScrollHandlerId=-1;this.handlerRef=null;}
|
disconnect(elementId){this.logger('[MudBlazor | ResizeObserver] Try to unobserve element with id',{elementId});var affectedObservedElement=this._observervedElements.find((x)=>x.id==elementId);if(affectedObservedElement){var element=affectedObservedElement.element;this._resizeObserver.unobserve(element);this.logger('[MudBlazor | ResizeObserver] Element found. Ubobserving size changes of element',{element});var index=this._observervedElements.indexOf(affectedObservedElement);this._observervedElements.splice(index,1);}}
|
||||||
listenForScroll(dotnetReference,selector){let element=selector?document.querySelector(selector):document;this.handlerRef=this.throttleScrollHandler.bind(this,dotnetReference);element.addEventListener('scroll',this.handlerRef,false);}
|
cancelListener(){this.logger('[MudBlazor | ResizeObserver] Closing ResizeObserver. Detaching all observed elements');this._resizeObserver.disconnect();this._dotNetRef=undefined;}}
|
||||||
throttleScrollHandler(dotnetReference,event){clearTimeout(this.throttleScrollHandlerId);this.throttleScrollHandlerId=window.setTimeout(this.scrollHandler.bind(this,dotnetReference,event),100);}
|
window.mudResizeObserver=new MudResizeObserverFactory();class MudElementReference{constructor(){this.listenerId=0;this.eventListeners={};}
|
||||||
scrollHandler(dotnetReference,event){try{let element=event.target;let scrollTop=element.scrollTop;let scrollHeight=element.scrollHeight;let scrollWidth=element.scrollWidth;let scrollLeft=element.scrollLeft;let nodeName=element.nodeName;let firstChild=element.firstElementChild;let firstChildBoundingClientRect=firstChild.getBoundingClientRect();dotnetReference.invokeMethodAsync('RaiseOnScroll',{firstChildBoundingClientRect,scrollLeft,scrollTop,scrollHeight,scrollWidth,nodeName,});}catch(error){console.log('[MudBlazor] Error in scrollHandler:',{error});}}
|
|
||||||
cancelListener(selector){let element=selector?document.querySelector(selector):document;element.removeEventListener('scroll',this.handlerRef);}};window.mudScrollListener=new MudScrollListener();class MudElementReference{constructor(){this.listenerId=0;this.eventListeners={};}
|
|
||||||
focus(element){if(element)
|
focus(element){if(element)
|
||||||
{element.focus();}}
|
{element.focus();}}
|
||||||
blur(element){if(element){element.blur();}}
|
blur(element){if(element){element.blur();}}
|
||||||
@@ -145,61 +241,17 @@ element.addEventListener(eventName,listener,{passive:false});this.eventListeners
|
|||||||
removeDefaultPreventingHandler(element,eventName,listenerId){this.removeEventListener(element,eventName,listenerId);}
|
removeDefaultPreventingHandler(element,eventName,listenerId){this.removeEventListener(element,eventName,listenerId);}
|
||||||
addDefaultPreventingHandlers(element,eventNames){let listeners=[];for(const eventName of eventNames){let listenerId=this.addDefaultPreventingHandler(element,eventName);listeners.push(listenerId);}
|
addDefaultPreventingHandlers(element,eventNames){let listeners=[];for(const eventName of eventNames){let listenerId=this.addDefaultPreventingHandler(element,eventName);listeners.push(listenerId);}
|
||||||
return listeners;}
|
return listeners;}
|
||||||
removeDefaultPreventingHandlers(element,eventNames,listenerIds){for(let index=0;index<eventNames.length;++index){const eventName=eventNames[index];const listenerId=listenerIds[index];this.removeDefaultPreventingHandler(element,eventName,listenerId);}}};window.mudElementRef=new MudElementReference();class MudKeyInterceptorFactory{connect(dotNetRef,elementId,options){if(!elementId)
|
removeDefaultPreventingHandlers(element,eventNames,listenerIds){for(let index=0;index<eventNames.length;++index){const eventName=eventNames[index];const listenerId=listenerIds[index];this.removeDefaultPreventingHandler(element,eventName,listenerId);}}};window.mudElementRef=new MudElementReference();class MudScrollListener{constructor(){this.throttleScrollHandlerId=-1;this.handlerRef=null;}
|
||||||
throw"elementId: expected element id!";var element=document.getElementById(elementId);if(!element)
|
listenForScroll(dotnetReference,selector){let element=selector?document.querySelector(selector):document;this.handlerRef=this.throttleScrollHandler.bind(this,dotnetReference);element.addEventListener('scroll',this.handlerRef,false);}
|
||||||
throw"no element found for id: "+elementId;if(!element.mudKeyInterceptor)
|
throttleScrollHandler(dotnetReference,event){clearTimeout(this.throttleScrollHandlerId);this.throttleScrollHandlerId=window.setTimeout(this.scrollHandler.bind(this,dotnetReference,event),100);}
|
||||||
element.mudKeyInterceptor=new MudKeyInterceptor(dotNetRef,options);element.mudKeyInterceptor.connect(element);}
|
scrollHandler(dotnetReference,event){try{let element=event.target;let scrollTop=element.scrollTop;let scrollHeight=element.scrollHeight;let scrollWidth=element.scrollWidth;let scrollLeft=element.scrollLeft;let nodeName=element.nodeName;let firstChild=element.firstElementChild;let firstChildBoundingClientRect=firstChild.getBoundingClientRect();dotnetReference.invokeMethodAsync('RaiseOnScroll',{firstChildBoundingClientRect,scrollLeft,scrollTop,scrollHeight,scrollWidth,nodeName,});}catch(error){console.log('[MudBlazor] Error in scrollHandler:',{error});}}
|
||||||
updatekey(elementId,option){var element=document.getElementById(elementId);if(!element||!element.mudKeyInterceptor)
|
cancelListener(selector){let element=selector?document.querySelector(selector):document;element.removeEventListener('scroll',this.handlerRef);}};window.mudScrollListener=new MudScrollListener();class MudWindow{copyToClipboard(text){navigator.clipboard.writeText(text);}
|
||||||
return;element.mudKeyInterceptor.updatekey(option);}
|
changeCssById(id,css){var element=document.getElementById(id);if(element){element.className=css;}}
|
||||||
disconnect(elementId){var element=document.getElementById(elementId);if(!element||!element.mudKeyInterceptor)
|
updateStyleProperty(elementId,propertyName,value){const element=document.getElementById(elementId);if(element){element.style.setProperty(propertyName,value);}}
|
||||||
return;element.mudKeyInterceptor.disconnect();}}
|
changeGlobalCssVariable(name,newValue){document.documentElement.style.setProperty(name,newValue);}
|
||||||
window.mudKeyInterceptor=new MudKeyInterceptorFactory();class MudKeyInterceptor{constructor(dotNetRef,options){this._dotNetRef=dotNetRef;this._options=options;this.logger=options.enableLogging?console.log:(message)=>{};this.logger('[MudBlazor | KeyInterceptor] Interceptor initialized',{options});}
|
open(args){window.open(args);}}
|
||||||
connect(element){if(!this._options)
|
window.mudWindow=new MudWindow();function setRippleOffset(event,target){const rect=target.getBoundingClientRect();const x=event.clientX-rect.left-rect.width/2;const y=event.clientY-rect.top-rect.height/2;target.style.setProperty("--mud-ripple-offset-x",`${x}px`);target.style.setProperty("--mud-ripple-offset-y",`${y}px`);}
|
||||||
return;if(!this._options.keys)
|
document.addEventListener("click",function(event){const target=event.target.closest(".mud-ripple");if(target){setRippleOffset(event,target);}});class MudScrollSpy{constructor(){this.lastKnowElement=null;this.handlerRef=null;}
|
||||||
throw"_options.keys: array of KeyOptions expected";if(!this._options.targetClass)
|
|
||||||
throw"_options.targetClass: css class name expected";if(this._observer){return;}
|
|
||||||
var targetClass=this._options.targetClass;this.logger('[MudBlazor | KeyInterceptor] Start observing DOM of element for changes to child with class ',{element,targetClass});this._element=element;this._observer=new MutationObserver(this.onDomChanged);this._observer.mudKeyInterceptor=this;this._observer.observe(this._element,{attributes:false,childList:true,subtree:true});this._observedChildren=[];this._keyOptions={};this._regexOptions=[];for(const keyOption of this._options.keys){if(!keyOption||!keyOption.key){this.logger('[MudBlazor | KeyInterceptor] got invalid key options: ',keyOption);continue;}
|
|
||||||
this.setKeyOption(keyOption)}
|
|
||||||
this.logger('[MudBlazor | KeyInterceptor] key options: ',this._keyOptions);if(this._regexOptions.size>0)
|
|
||||||
this.logger('[MudBlazor | KeyInterceptor] regex options: ',this._regexOptions);for(const child of this._element.getElementsByClassName(targetClass)){this.attachHandlers(child);}}
|
|
||||||
setKeyOption(keyOption){if(keyOption.key.length>2&&keyOption.key.startsWith('/')&&keyOption.key.endsWith('/')){keyOption.regex=new RegExp(keyOption.key.substring(1,keyOption.key.length-1));this._regexOptions.push(keyOption);}
|
|
||||||
else
|
|
||||||
this._keyOptions[keyOption.key.toLowerCase()]=keyOption;var whitespace=new RegExp("\\s","g");keyOption.preventDown=(keyOption.preventDown||"none").replace(whitespace,"").toLowerCase();keyOption.preventUp=(keyOption.preventUp||"none").replace(whitespace,"").toLowerCase();keyOption.stopDown=(keyOption.stopDown||"none").replace(whitespace,"").toLowerCase();keyOption.stopUp=(keyOption.stopUp||"none").replace(whitespace,"").toLowerCase();}
|
|
||||||
updatekey(updatedOption){var option=this._keyOptions[updatedOption.key.toLowerCase()];option||this.logger('[MudBlazor | KeyInterceptor] updating option failed: key not registered');this.setKeyOption(updatedOption);this.logger('[MudBlazor | KeyInterceptor] updated option ',{option,updatedOption});}
|
|
||||||
disconnect(){if(!this._observer)
|
|
||||||
return;this.logger('[MudBlazor | KeyInterceptor] disconnect mutation observer and event handlers');this._observer.disconnect();this._observer=null;for(const child of this._observedChildren)
|
|
||||||
this.detachHandlers(child);}
|
|
||||||
attachHandlers(child){this.logger('[MudBlazor | KeyInterceptor] attaching handlers ',{child});if(this._observedChildren.indexOf(child)>-1){return;}
|
|
||||||
child.mudKeyInterceptor=this;child.addEventListener('keydown',this.onKeyDown);child.addEventListener('keyup',this.onKeyUp);this._observedChildren.push(child);}
|
|
||||||
detachHandlers(child){this.logger('[MudBlazor | KeyInterceptor] detaching handlers ',{child});child.removeEventListener('keydown',this.onKeyDown);child.removeEventListener('keyup',this.onKeyUp);this._observedChildren=this._observedChildren.filter(x=>x!==child);}
|
|
||||||
onDomChanged(mutationsList,observer){var self=this.mudKeyInterceptor;var targetClass=self._options.targetClass;for(const mutation of mutationsList){for(const element of mutation.addedNodes){if(element.classList&&element.classList.contains(targetClass))
|
|
||||||
self.attachHandlers(element);}
|
|
||||||
for(const element of mutation.removedNodes){if(element.classList&&element.classList.contains(targetClass))
|
|
||||||
self.detachHandlers(element);}}}
|
|
||||||
matchesKeyCombination(option,args){if(!option||option==="none")
|
|
||||||
return false;if(option==="any")
|
|
||||||
return true;var shift=args.shiftKey;var ctrl=args.ctrlKey;var alt=args.altKey;var meta=args.metaKey;var any=shift||ctrl||alt||meta;if(any&&option==="key+any")
|
|
||||||
return true;if(!any&&option.includes("key+none"))
|
|
||||||
return true;if(!any)
|
|
||||||
return false;var combi=`key${shift?"+shift":""}${ctrl?"+ctrl":""}${alt?"+alt":""}${meta?"+meta":""}`;return option.includes(combi);}
|
|
||||||
onKeyDown(args){var self=this.mudKeyInterceptor;var key=args.key.toLowerCase();self.logger('[MudBlazor | KeyInterceptor] down "'+key+'"',args);var invoke=false;if(self._keyOptions.hasOwnProperty(key)){var keyOptions=self._keyOptions[key];self.logger('[MudBlazor | KeyInterceptor] options for "'+key+'"',keyOptions);self.processKeyDown(args,keyOptions);if(keyOptions.subscribeDown)
|
|
||||||
invoke=true;}
|
|
||||||
for(const keyOptions of self._regexOptions){if(keyOptions.regex.test(key)){self.logger('[MudBlazor | KeyInterceptor] regex options for "'+key+'"',keyOptions);self.processKeyDown(args,keyOptions);if(keyOptions.subscribeDown)
|
|
||||||
invoke=true;}}
|
|
||||||
if(invoke){var eventArgs=self.toKeyboardEventArgs(args);eventArgs.Type="keydown";self._dotNetRef.invokeMethodAsync('OnKeyDown',eventArgs);}}
|
|
||||||
processKeyDown(args,keyOptions){if(this.matchesKeyCombination(keyOptions.preventDown,args))
|
|
||||||
args.preventDefault();if(this.matchesKeyCombination(keyOptions.stopDown,args))
|
|
||||||
args.stopPropagation();}
|
|
||||||
onKeyUp(args){var self=this.mudKeyInterceptor;var key=args.key.toLowerCase();self.logger('[MudBlazor | KeyInterceptor] up "'+key+'"',args);var invoke=false;if(self._keyOptions.hasOwnProperty(key)){var keyOptions=self._keyOptions[key];self.processKeyUp(args,keyOptions);if(keyOptions.subscribeUp)
|
|
||||||
invoke=true;}
|
|
||||||
for(const keyOptions of self._regexOptions){if(keyOptions.regex.test(key)){self.processKeyUp(args,keyOptions);if(keyOptions.subscribeUp)
|
|
||||||
invoke=true;}}
|
|
||||||
if(invoke){var eventArgs=self.toKeyboardEventArgs(args);eventArgs.Type="keyup";self._dotNetRef.invokeMethodAsync('OnKeyUp',eventArgs);}}
|
|
||||||
processKeyUp(args,keyOptions){if(this.matchesKeyCombination(keyOptions.preventUp,args))
|
|
||||||
args.preventDefault();if(this.matchesKeyCombination(keyOptions.stopUp,args))
|
|
||||||
args.stopPropagation();}
|
|
||||||
toKeyboardEventArgs(args){return{Key:args.key,Code:args.code,Location:args.location,Repeat:args.repeat,CtrlKey:args.ctrlKey,ShiftKey:args.shiftKey,AltKey:args.altKey,MetaKey:args.metaKey};}}
|
|
||||||
class MudScrollSpy{constructor(){this.lastKnowElement=null;this.handlerRef=null;}
|
|
||||||
spying(dotnetReference,containerSelector,sectionClassSelector){this.lastKnowElement=null;this.handlerRef=this.handleScroll.bind(this,dotnetReference,containerSelector,sectionClassSelector);document.addEventListener('scroll',this.handlerRef,true);window.addEventListener('resize',this.handlerRef,true);}
|
spying(dotnetReference,containerSelector,sectionClassSelector){this.lastKnowElement=null;this.handlerRef=this.handleScroll.bind(this,dotnetReference,containerSelector,sectionClassSelector);document.addEventListener('scroll',this.handlerRef,true);window.addEventListener('resize',this.handlerRef,true);}
|
||||||
handleScroll(dotnetReference,containerSelector,sectionClassSelector,event){const container=document.querySelector(containerSelector);if(container===null){return;}
|
handleScroll(dotnetReference,containerSelector,sectionClassSelector,event){const container=document.querySelector(containerSelector);if(container===null){return;}
|
||||||
const elements=document.getElementsByClassName(sectionClassSelector);if(elements.length===0){return;}
|
const elements=document.getElementsByClassName(sectionClassSelector);if(elements.length===0){return;}
|
||||||
@@ -225,64 +277,13 @@ if(entry.projection){if(typeof entry.projection==="function"){entry.projection.a
|
|||||||
entry.reference.invokeMethodAsync('OnEventOccur',key,JSON.stringify(eventEntry));}
|
entry.reference.invokeMethodAsync('OnEventOccur',key,JSON.stringify(eventEntry));}
|
||||||
unsubscribe(key){const entry=this.mapper[key];if(!entry){return;}
|
unsubscribe(key){const entry=this.mapper[key];if(!entry){return;}
|
||||||
entry.reference=null;if(document==entry.elementId){document.removeEventListener(entry.eventName,entry.handler,false);}else{const elem=document.getElementById(entry.elementId);if(elem){elem.removeEventListener(entry.eventName,entry.handler,false);}}
|
entry.reference=null;if(document==entry.elementId){document.removeEventListener(entry.eventName,entry.handler,false);}else{const elem=document.getElementById(entry.elementId);if(elem){elem.removeEventListener(entry.eventName,entry.handler,false);}}
|
||||||
delete this.mapper[key];}};window.mudThrottledEventManager=new MudThrottledEventManager();window.mudEventProjections={correctOffset:function(eventEntry,event){var target=event.target.getBoundingClientRect();eventEntry.offsetX=event.clientX-target.x;eventEntry.offsetY=event.clientY-target.y;}};const darkThemeMediaQuery=window.matchMedia("(prefers-color-scheme: dark)");window.darkModeChange=()=>{return darkThemeMediaQuery.matches;};function darkModeChangeListener(e){dotNetHelperTheme.invokeMethodAsync('SystemPreferenceChanged',e.matches);}
|
delete this.mapper[key];}};window.mudThrottledEventManager=new MudThrottledEventManager();window.mudEventProjections={correctOffset:function(eventEntry,event){var target=event.target.getBoundingClientRect();eventEntry.offsetX=event.clientX-target.x;eventEntry.offsetY=event.clientY-target.y;}};window.getTabbableElements=(element)=>{return element.querySelectorAll("a[href]:not([tabindex='-1']),"+"area[href]:not([tabindex='-1']),"+"button:not([disabled]):not([tabindex='-1']),"+"input:not([disabled]):not([tabindex='-1']):not([type='hidden']),"+"select:not([disabled]):not([tabindex='-1']),"+"textarea:not([disabled]):not([tabindex='-1']),"+"iframe:not([tabindex='-1']),"+"details:not([tabindex='-1']),"+"[tabindex]:not([tabindex='-1']),"+"[contentEditable=true]:not([tabindex='-1'])");};window.serializeParameter=(data,spec)=>{if(typeof data=="undefined"||data===null){return null;}
|
||||||
|
if(typeof data==="number"||typeof data==="string"||typeof data=="boolean"){return data;}
|
||||||
|
let res=(Array.isArray(data))?[]:{};if(!spec){spec="*";}
|
||||||
|
for(let i in data){let currentMember=data[i];if(typeof currentMember==='function'||currentMember===null){continue;}
|
||||||
|
let currentMemberSpec;if(spec!="*"){currentMemberSpec=Array.isArray(data)?spec:spec[i];if(!currentMemberSpec){continue;}}else{currentMemberSpec="*"}
|
||||||
|
if(typeof currentMember==='object'){if(Array.isArray(currentMember)||currentMember.length){res[i]=[];for(let j=0;j<currentMember.length;j++){const arrayItem=currentMember[j];if(typeof arrayItem==='object'){res[i].push(this.serializeParameter(arrayItem,currentMemberSpec));}else{res[i].push(arrayItem);}}}else{if(currentMember.length===0){res[i]=[];}else{res[i]=this.serializeParameter(currentMember,currentMemberSpec);}}}else{if(currentMember===Infinity){currentMember="Infinity";}
|
||||||
|
if(currentMember!==null){res[i]=currentMember;}}}
|
||||||
|
return res;};const darkThemeMediaQuery=window.matchMedia("(prefers-color-scheme: dark)");window.darkModeChange=()=>{return darkThemeMediaQuery.matches;};function darkModeChangeListener(e){dotNetHelperTheme.invokeMethodAsync('SystemPreferenceChanged',e.matches);}
|
||||||
function watchDarkThemeMedia(dotNetHelper){dotNetHelperTheme=dotNetHelper;darkThemeMediaQuery.addEventListener('change',darkModeChangeListener);}
|
function watchDarkThemeMedia(dotNetHelper){dotNetHelperTheme=dotNetHelper;darkThemeMediaQuery.addEventListener('change',darkModeChangeListener);}
|
||||||
function stopWatchingDarkThemeMedia(){darkThemeMediaQuery.removeEventListener('change',darkModeChangeListener);}
|
function stopWatchingDarkThemeMedia(){darkThemeMediaQuery.removeEventListener('change',darkModeChangeListener);}
|
||||||
window.mudpopoverHelper={calculatePopoverPosition:function(list,boundingRect,selfRect){let top=0;let left=0;if(list.indexOf('mud-popover-anchor-top-left')>=0){left=boundingRect.left;top=boundingRect.top;}else if(list.indexOf('mud-popover-anchor-top-center')>=0){left=boundingRect.left+boundingRect.width/2;top=boundingRect.top;}else if(list.indexOf('mud-popover-anchor-top-right')>=0){left=boundingRect.left+boundingRect.width;top=boundingRect.top;}else if(list.indexOf('mud-popover-anchor-center-left')>=0){left=boundingRect.left;top=boundingRect.top+boundingRect.height/2;}else if(list.indexOf('mud-popover-anchor-center-center')>=0){left=boundingRect.left+boundingRect.width/2;top=boundingRect.top+boundingRect.height/2;}else if(list.indexOf('mud-popover-anchor-center-right')>=0){left=boundingRect.left+boundingRect.width;top=boundingRect.top+boundingRect.height/2;}else if(list.indexOf('mud-popover-anchor-bottom-left')>=0){left=boundingRect.left;top=boundingRect.top+boundingRect.height;}else if(list.indexOf('mud-popover-anchor-bottom-center')>=0){left=boundingRect.left+boundingRect.width/2;top=boundingRect.top+boundingRect.height;}else if(list.indexOf('mud-popover-anchor-bottom-right')>=0){left=boundingRect.left+boundingRect.width;top=boundingRect.top+boundingRect.height;}
|
|
||||||
let offsetX=0;let offsetY=0;if(list.indexOf('mud-popover-top-left')>=0){offsetX=0;offsetY=0;}else if(list.indexOf('mud-popover-top-center')>=0){offsetX=-selfRect.width/2;offsetY=0;}else if(list.indexOf('mud-popover-top-right')>=0){offsetX=-selfRect.width;offsetY=0;}
|
|
||||||
else if(list.indexOf('mud-popover-center-left')>=0){offsetX=0;offsetY=-selfRect.height/2;}else if(list.indexOf('mud-popover-center-center')>=0){offsetX=-selfRect.width/2;offsetY=-selfRect.height/2;}else if(list.indexOf('mud-popover-center-right')>=0){offsetX=-selfRect.width;offsetY=-selfRect.height/2;}
|
|
||||||
else if(list.indexOf('mud-popover-bottom-left')>=0){offsetX=0;offsetY=-selfRect.height;}else if(list.indexOf('mud-popover-bottom-center')>=0){offsetX=-selfRect.width/2;offsetY=-selfRect.height;}else if(list.indexOf('mud-popover-bottom-right')>=0){offsetX=-selfRect.width;offsetY=-selfRect.height;}
|
|
||||||
return{top:top,left:left,offsetX:offsetX,offsetY:offsetY};},flipClassReplacements:{'top':{'mud-popover-top-left':'mud-popover-bottom-left','mud-popover-top-center':'mud-popover-bottom-center','mud-popover-anchor-bottom-center':'mud-popover-anchor-top-center','mud-popover-top-right':'mud-popover-bottom-right',},'left':{'mud-popover-top-left':'mud-popover-top-right','mud-popover-center-left':'mud-popover-center-right','mud-popover-anchor-center-right':'mud-popover-anchor-center-left','mud-popover-bottom-left':'mud-popover-bottom-right',},'right':{'mud-popover-top-right':'mud-popover-top-left','mud-popover-center-right':'mud-popover-center-left','mud-popover-anchor-center-left':'mud-popover-anchor-center-right','mud-popover-bottom-right':'mud-popover-bottom-left',},'bottom':{'mud-popover-bottom-left':'mud-popover-top-left','mud-popover-bottom-center':'mud-popover-top-center','mud-popover-anchor-top-center':'mud-popover-anchor-bottom-center','mud-popover-bottom-right':'mud-popover-top-right',},'top-and-left':{'mud-popover-top-left':'mud-popover-bottom-right',},'top-and-right':{'mud-popover-top-right':'mud-popover-bottom-left',},'bottom-and-left':{'mud-popover-bottom-left':'mud-popover-top-right',},'bottom-and-right':{'mud-popover-bottom-right':'mud-popover-top-left',},},flipMargin:0,getPositionForFlippedPopver:function(inputArray,selector,boundingRect,selfRect){const classList=[];for(var i=0;i<inputArray.length;i++){const item=inputArray[i];const replacments=window.mudpopoverHelper.flipClassReplacements[selector][item];if(replacments){classList.push(replacments);}
|
|
||||||
else{classList.push(item);}}
|
|
||||||
return window.mudpopoverHelper.calculatePopoverPosition(classList,boundingRect,selfRect);},placePopover:function(popoverNode,classSelector){if(popoverNode&&popoverNode.parentNode){const id=popoverNode.id.substr(8);const popoverContentNode=document.getElementById('popovercontent-'+id);if(!popoverContentNode){return;}
|
|
||||||
if(popoverContentNode.classList.contains('mud-popover-open')==false){return;}
|
|
||||||
if(classSelector){if(popoverContentNode.classList.contains(classSelector)==false){return;}}
|
|
||||||
const boundingRect=popoverNode.parentNode.getBoundingClientRect();if(popoverContentNode.classList.contains('mud-popover-relative-width')){popoverContentNode.style['max-width']=(boundingRect.width)+'px';}
|
|
||||||
const selfRect=popoverContentNode.getBoundingClientRect();const classList=popoverContentNode.classList;const classListArray=Array.from(popoverContentNode.classList);const postion=window.mudpopoverHelper.calculatePopoverPosition(classListArray,boundingRect,selfRect);let left=postion.left;let top=postion.top;let offsetX=postion.offsetX;let offsetY=postion.offsetY;if(classList.contains('mud-popover-overflow-flip-onopen')||classList.contains('mud-popover-overflow-flip-always')){const appBarElements=document.getElementsByClassName("mud-appbar mud-appbar-fixed-top");let appBarOffset=0;if(appBarElements.length>0){appBarOffset=appBarElements[0].getBoundingClientRect().height;}
|
|
||||||
const graceMargin=window.mudpopoverHelper.flipMargin;const deltaToLeft=left+offsetX;const deltaToRight=window.innerWidth-left-selfRect.width;const deltaTop=top-selfRect.height-appBarOffset;const spaceToTop=top-appBarOffset;const deltaBottom=window.innerHeight-top-selfRect.height;let selector=popoverContentNode.mudPopoverFliped;if(!selector){if(classList.contains('mud-popover-top-left')){if(deltaBottom<graceMargin&&deltaToRight<graceMargin&&spaceToTop>=selfRect.height&&deltaToLeft>=selfRect.width){selector='top-and-left';}else if(deltaBottom<graceMargin&&spaceToTop>=selfRect.height){selector='top';}else if(deltaToRight<graceMargin&&deltaToLeft>=selfRect.width){selector='left';}}else if(classList.contains('mud-popover-top-center')){if(deltaBottom<graceMargin&&spaceToTop>=selfRect.height){selector='top';}}else if(classList.contains('mud-popover-top-right')){if(deltaBottom<graceMargin&&deltaToLeft<graceMargin&&spaceToTop>=selfRect.height&&deltaToRight>=selfRect.width){selector='top-and-right';}else if(deltaBottom<graceMargin&&spaceToTop>=selfRect.height){selector='top';}else if(deltaToLeft<graceMargin&&deltaToRight>=selfRect.width){selector='right';}}
|
|
||||||
else if(classList.contains('mud-popover-center-left')){if(deltaToRight<graceMargin&&deltaToLeft>=selfRect.width){selector='left';}}
|
|
||||||
else if(classList.contains('mud-popover-center-right')){if(deltaToLeft<graceMargin&&deltaToRight>=selfRect.width){selector='right';}}
|
|
||||||
else if(classList.contains('mud-popover-bottom-left')){if(deltaTop<graceMargin&&deltaToRight<graceMargin&&deltaBottom>=0&&deltaToLeft>=selfRect.width){selector='bottom-and-left';}else if(deltaTop<graceMargin&&deltaBottom>=0){selector='bottom';}else if(deltaToRight<graceMargin&&deltaToLeft>=selfRect.width){selector='left';}}else if(classList.contains('mud-popover-bottom-center')){if(deltaTop<graceMargin&&deltaBottom>=0){selector='bottom';}}else if(classList.contains('mud-popover-bottom-right')){if(deltaTop<graceMargin&&deltaToLeft<graceMargin&&deltaBottom>=0&&deltaToRight>=selfRect.width){selector='bottom-and-right';}else if(deltaTop<graceMargin&&deltaBottom>=0){selector='bottom';}else if(deltaToLeft<graceMargin&&deltaToRight>=selfRect.width){selector='right';}}}
|
|
||||||
if(selector&&selector!='none'){const newPosition=window.mudpopoverHelper.getPositionForFlippedPopver(classListArray,selector,boundingRect,selfRect);left=newPosition.left;top=newPosition.top;offsetX=newPosition.offsetX;offsetY=newPosition.offsetY;popoverContentNode.setAttribute('data-mudpopover-flip','flipped');}
|
|
||||||
else{popoverContentNode.removeAttribute('data-mudpopover-flip');}
|
|
||||||
if(classList.contains('mud-popover-overflow-flip-onopen')){if(!popoverContentNode.mudPopoverFliped){popoverContentNode.mudPopoverFliped=selector||'none';}}}
|
|
||||||
if(popoverContentNode.classList.contains('mud-popover-fixed')){}
|
|
||||||
else if(window.getComputedStyle(popoverNode).position=='fixed'){popoverContentNode.style['position']='fixed';}
|
|
||||||
else{offsetX+=window.scrollX;offsetY+=window.scrollY}
|
|
||||||
popoverContentNode.style['left']=(left+offsetX)+'px';popoverContentNode.style['top']=(top+offsetY)+'px';if(window.getComputedStyle(popoverNode).getPropertyValue('z-index')!='auto'){popoverContentNode.style['z-index']=window.getComputedStyle(popoverNode).getPropertyValue('z-index');popoverContentNode.skipZIndex=true;}}},placePopoverByClassSelector:function(classSelector=null){var items=window.mudPopover.getAllObservedContainers();for(let i=0;i<items.length;i++){const popoverNode=document.getElementById('popover-'+items[i]);window.mudpopoverHelper.placePopover(popoverNode,classSelector);}},placePopoverByNode:function(target){const id=target.id.substr(15);const popoverNode=document.getElementById('popover-'+id);window.mudpopoverHelper.placePopover(popoverNode);},countProviders:function(){return document.querySelectorAll(".mud-popover-provider").length;}}
|
|
||||||
class MudPopover{constructor(){this.map={};this.contentObserver=null;this.mainContainerClass=null;}
|
|
||||||
callback(id,mutationsList,observer){for(const mutation of mutationsList){if(mutation.type==='attributes'){const target=mutation.target
|
|
||||||
if(mutation.attributeName=='class'){if(target.classList.contains('mud-popover-overflow-flip-onopen')&&target.classList.contains('mud-popover-open')==false){target.mudPopoverFliped=null;target.removeAttribute('data-mudpopover-flip');}
|
|
||||||
window.mudpopoverHelper.placePopoverByNode(target);}
|
|
||||||
else if(mutation.attributeName=='data-ticks'){const tickAttribute=target.getAttribute('data-ticks');const parent=target.parentElement;const tickValues=[];let max=-1;if(parent){for(let i=0;i<parent.children.length;i++){const childNode=parent.children[i];const tickValue=parseInt(childNode.getAttribute('data-ticks'));if(tickValue==0){continue;}
|
|
||||||
if(tickValues.indexOf(tickValue)>=0){continue;}
|
|
||||||
tickValues.push(tickValue);if(tickValue>max){max=tickValue;}}}
|
|
||||||
if(tickValues.length==0){continue;}
|
|
||||||
const sortedTickValues=tickValues.sort((x,y)=>x-y);for(let i=0;i<parent.children.length;i++){const childNode=parent.children[i];const tickValue=parseInt(childNode.getAttribute('data-ticks'));if(tickValue==0){continue;}
|
|
||||||
if(childNode.skipZIndex==true){continue;}
|
|
||||||
childNode.style['z-index']='calc(var(--mud-zindex-popover) + '+(sortedTickValues.indexOf(tickValue)+3).toString()+')';}}}}}
|
|
||||||
initialize(containerClass,flipMargin){const mainContent=document.getElementsByClassName(containerClass);if(mainContent.length==0){return;}
|
|
||||||
if(flipMargin){window.mudpopoverHelper.flipMargin=flipMargin;}
|
|
||||||
this.mainContainerClass=containerClass;if(!mainContent[0].mudPopoverMark){mainContent[0].mudPopoverMark="mudded";if(this.contentObserver!=null){this.contentObserver.disconnect();this.contentObserver=null;}
|
|
||||||
this.contentObserver=new ResizeObserver(entries=>{window.mudpopoverHelper.placePopoverByClassSelector();});this.contentObserver.observe(mainContent[0]);}}
|
|
||||||
connect(id){this.initialize(this.mainContainerClass);const popoverNode=document.getElementById('popover-'+id);const popoverContentNode=document.getElementById('popovercontent-'+id);if(popoverNode&&popoverNode.parentNode&&popoverContentNode){window.mudpopoverHelper.placePopover(popoverNode);const config={attributeFilter:['class','data-ticks']};const observer=new MutationObserver(this.callback.bind(this,id));observer.observe(popoverContentNode,config);const resizeObserver=new ResizeObserver(entries=>{for(let entry of entries){const target=entry.target;for(var i=0;i<target.childNodes.length;i++){const childNode=target.childNodes[i];if(childNode.id&&childNode.id.startsWith('popover-')){window.mudpopoverHelper.placePopover(childNode);}}}});resizeObserver.observe(popoverNode.parentNode);const contentNodeObserver=new ResizeObserver(entries=>{for(let entry of entries){var target=entry.target;window.mudpopoverHelper.placePopoverByNode(target);}});contentNodeObserver.observe(popoverContentNode);this.map[id]={mutationObserver:observer,resizeObserver:resizeObserver,contentNodeObserver:contentNodeObserver};}}
|
|
||||||
disconnect(id){if(this.map[id]){const item=this.map[id]
|
|
||||||
item.mutationObserver.disconnect();item.resizeObserver.disconnect();item.contentNodeObserver.disconnect();delete this.map[id];}}
|
|
||||||
dispose(){for(var i in this.map){disconnect(i);}
|
|
||||||
this.contentObserver.disconnect();this.contentObserver=null;}
|
|
||||||
getAllObservedContainers(){const result=[];for(var i in this.map){result.push(i);}
|
|
||||||
return result;}}
|
|
||||||
window.mudPopover=new MudPopover();window.addEventListener('scroll',()=>{window.mudpopoverHelper.placePopoverByClassSelector('mud-popover-fixed');window.mudpopoverHelper.placePopoverByClassSelector('mud-popover-overflow-flip-always');});window.addEventListener('resize',()=>{window.mudpopoverHelper.placePopoverByClassSelector();});class MudScrollManager{scrollToYear(elementId,offset){let element=document.getElementById(elementId);if(element){element.parentNode.scrollTop=element.offsetTop-element.parentNode.offsetTop-element.scrollHeight*3;}}
|
|
||||||
scrollToListItem(elementId){let element=document.getElementById(elementId);if(element){let parent=element.parentElement;if(parent){parent.scrollTop=element.offsetTop;}}}
|
|
||||||
scrollTo(selector,left,top,behavior){let element=document.querySelector(selector)||document.documentElement;element.scrollTo({left,top,behavior});}
|
|
||||||
scrollIntoView(selector,behavior){let element=document.querySelector(selector)||document.documentElement;if(element)
|
|
||||||
element.scrollIntoView({behavior,block:'center',inline:'start'});}
|
|
||||||
scrollToBottom(selector,behavior){let element=document.querySelector(selector);if(element){element.scrollTo({top:element.scrollHeight,behavior:behavior});}else{window.scrollTo({top:document.body.scrollHeight,behavior:behavior});}}
|
|
||||||
lockScroll(selector,lockclass){let element=document.querySelector(selector)||document.body;let hasScrollBar=window.innerWidth>document.body.clientWidth;if(hasScrollBar){element.classList.add(lockclass);}else{let lockClassNoPadding=lockclass+"-no-padding";element.classList.add(lockClassNoPadding);}}
|
|
||||||
unlockScroll(selector,lockclass){let element=document.querySelector(selector)||document.body;element.classList.remove(lockclass);element.classList.remove(lockclass+"-no-padding");}};window.mudScrollManager=new MudScrollManager();window.mudDragAndDrop={initDropZone:(id)=>{const elem=document.getElementById(id);elem.addEventListener('dragover',()=>event.preventDefault());elem.addEventListener('dragstart',()=>event.dataTransfer.setData('',event.target.id));},makeDropZonesNotRelative:()=>{var firstDropItems=Array.from(document.getElementsByClassName('mud-drop-item')).filter(x=>x.getAttribute('index')=="-1");for(let dropItem of firstDropItems){dropItem.style.position='static';}
|
|
||||||
const dropZones=document.getElementsByClassName('mud-drop-zone');for(let dropZone of dropZones){dropZone.style.position='unset';}},getDropZoneIdentifierOnPosition:(x,y)=>{const elems=document.elementsFromPoint(x,y);const dropZones=elems.filter(e=>e.classList.contains('mud-drop-zone'))
|
|
||||||
const dropZone=dropZones[0];if(dropZone){return dropZone.getAttribute('identifier')||"";}
|
|
||||||
return"";},getDropIndexOnPosition:(x,y,id)=>{const elems=document.elementsFromPoint(x,y);const dropItems=elems.filter(e=>e.classList.contains('mud-drop-item')&&e.id!=id)
|
|
||||||
const dropItem=dropItems[0];if(dropItem){return dropItem.getAttribute('index')||"";}
|
|
||||||
return"";},makeDropZonesRelative:()=>{const dropZones=document.getElementsByClassName('mud-drop-zone');for(let dropZone of dropZones){dropZone.style.position='relative';}
|
|
||||||
var firstDropItems=Array.from(document.getElementsByClassName('mud-drop-item')).filter(x=>x.getAttribute('index')=="-1");for(let dropItem of firstDropItems){dropItem.style.position='relative';}},moveItemByDifference:(id,dx,dy)=>{const elem=document.getElementById(id);var tx=(parseFloat(elem.getAttribute('data-x'))||0)+dx;var ty=(parseFloat(elem.getAttribute('data-y'))||0)+dy;elem.style.webkitTransform=elem.style.transform='translate3d('+tx+'px, '+ty+'px, 10px)';elem.setAttribute('data-x',tx);elem.setAttribute('data-y',ty);},resetItem:(id)=>{const elem=document.getElementById(id);if(elem){elem.style.webkitTransform=elem.style.transform='';elem.setAttribute('data-x',0);elem.setAttribute('data-y',0);}}};
|
|
||||||
+19
-8
@@ -5,18 +5,28 @@ You just want to use the app? Then simply [download the appropriate setup for yo
|
|||||||
1. Install the [.NET 8 SDK](https://dotnet.microsoft.com/en-us/download/dotnet/8.0).
|
1. Install the [.NET 8 SDK](https://dotnet.microsoft.com/en-us/download/dotnet/8.0).
|
||||||
2. [Install the Rust compiler](https://www.rust-lang.org/tools/install) in the latest version.
|
2. [Install the Rust compiler](https://www.rust-lang.org/tools/install) in the latest version.
|
||||||
3. Met the prerequisites for building [Tauri](https://tauri.app/v1/guides/getting-started/prerequisites/). Node.js is **not** required, though.
|
3. Met the prerequisites for building [Tauri](https://tauri.app/v1/guides/getting-started/prerequisites/). Node.js is **not** required, though.
|
||||||
4. Install the Tauri CLI by running `cargo install tauri-cli`.
|
4. Install the Tauri CLI by running `cargo install --version 1.6.2 tauri-cli`.
|
||||||
5. [Install NuShell](https://www.nushell.sh/) when you want to prepare a release or build a local binary. NuShell works on all operating systems and is required because the build script is written in NuShell.
|
5. [Install NuShell](https://www.nushell.sh/). NuShell works on all operating systems and is required because the build script is written in NuShell.
|
||||||
6. Clone the repository.
|
6. Clone the repository.
|
||||||
|
|
||||||
## Build instructions
|
## One-time mandatory steps
|
||||||
|
Regardless of whether you want to build the app locally for yourself (not trusting the pre-built binaries) or test your changes before creating a PR, you have to run the following commands at least once:
|
||||||
|
|
||||||
|
1. Open a terminal using NuShell.
|
||||||
|
2. Navigate to the `/app/MindWork AI Studio` directory within the repository.
|
||||||
|
3. Run `dotnet restore` to bring up the .NET dependencies.
|
||||||
|
4. Run `nu build.nu publish` to build the entire app.
|
||||||
|
|
||||||
|
This is necessary because the build script and the Tauri framework assume that the .NET app is available as a so-called "sidecar." Although the sidecar is only necessary for the final release and shipping, Tauri requires it to be present during development as well.
|
||||||
|
|
||||||
|
## Build AI Studio from source
|
||||||
In order to build MindWork AI Studio from source instead of using the pre-built binaries, follow these steps:
|
In order to build MindWork AI Studio from source instead of using the pre-built binaries, follow these steps:
|
||||||
1. Ensure you have met all the prerequisites.
|
1. Ensure you have met all the prerequisites.
|
||||||
2. Open a terminal with NuShell.
|
2. Open a terminal with NuShell.
|
||||||
3. Navigate to the `/app/MindWork AI Studio` directory within the repository.
|
3. Navigate to the `/app/MindWork AI Studio` directory within the repository.
|
||||||
4. To build the current version, run `nu build.nu publish`.
|
4. To build the current version, run `nu build.nu publish` to build the entire app.
|
||||||
- This will build the app for the current operating system, for both x64 (Intel, AMD) and ARM64 (e.g., Apple Silicon, Raspberry Pi).
|
- This will build the app for the current operating system, for both x64 (Intel, AMD) and ARM64 (e.g., Apple Silicon, Raspberry Pi).
|
||||||
- The setup program will be located in `runtime/target/release/bundle` afterward.
|
- The final setup program will be located in `runtime/target/release/bundle` afterward.
|
||||||
5. In order to create a new release:
|
5. In order to create a new release:
|
||||||
1. Before finishing the PR, make sure to create a changelog file in the `/app/MindWork AI Studio/wwwroot/changelog` directory. The file should be named `vX.Y.Z.md` and contain the changes made in the release (your changes and any other changes that are part of the release).
|
1. Before finishing the PR, make sure to create a changelog file in the `/app/MindWork AI Studio/wwwroot/changelog` directory. The file should be named `vX.Y.Z.md` and contain the changes made in the release (your changes and any other changes that are part of the release).
|
||||||
2. To prepare a new release, run `nu build.nu prepare <ACTION>`, where `<ACTION>` is either `patch`, `minor`, or `major`.
|
2. To prepare a new release, run `nu build.nu prepare <ACTION>`, where `<ACTION>` is either `patch`, `minor`, or `major`.
|
||||||
@@ -29,8 +39,9 @@ In order to build MindWork AI Studio from source instead of using the pre-built
|
|||||||
## Run the app locally with all your changes
|
## Run the app locally with all your changes
|
||||||
Do you want to test your changes before creating a PR? Follow these steps:
|
Do you want to test your changes before creating a PR? Follow these steps:
|
||||||
1. Ensure you have met all the prerequisites.
|
1. Ensure you have met all the prerequisites.
|
||||||
2. Open a terminal (in this case, it doesn't have to be NuShell).
|
2. At least once, you have to run the `nu build.nu publish` command (see above, "Build instructions"). This is necessary because the Tauri framework checks whether the .NET app as so-called "sidecar" is available. Although the sidecar is only necessary for the final release and shipping, Tauri requires it to be present during development.
|
||||||
3. Navigate to the `runtime` directory within the repository, e.g. `cd repos/mindwork-ai-studio/runtime`.
|
3. Open a terminal (in this case, it doesn't have to be NuShell).
|
||||||
4. Run `cargo run`.
|
4. Navigate to the `runtime` directory within the repository, e.g. `cd repos/mindwork-ai-studio/runtime`.
|
||||||
|
5. Run `cargo run`.
|
||||||
|
|
||||||
Cargo will compile the Rust code and start the runtime. The runtime will then start the .NET compiler. When the .NET source code is compiled, the app will start. You can now test your changes.
|
Cargo will compile the Rust code and start the runtime. The runtime will then start the .NET compiler. When the .NET source code is compiled, the app will start. You can now test your changes.
|
||||||
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+9
-9
@@ -1,9 +1,9 @@
|
|||||||
0.9.12
|
0.9.17
|
||||||
2024-09-15 20:49:12 UTC
|
2024-11-03 11:11:20 UTC
|
||||||
187
|
192
|
||||||
8.0.108 (commit 665a05cea7)
|
8.0.110 (commit 87a66bb3d1)
|
||||||
8.0.8 (commit 08338fcaa5)
|
8.0.10 (commit 81cabf2857)
|
||||||
1.81.0 (commit eeb90cda1)
|
1.82.0 (commit f6e511eec)
|
||||||
7.8.0
|
7.14.0
|
||||||
1.7.1
|
1.8.1
|
||||||
8715054dda6, release
|
14fc418aa68, release
|
||||||
Generated
+108
-48
@@ -75,9 +75,9 @@ checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arboard"
|
name = "arboard"
|
||||||
version = "3.4.0"
|
version = "3.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9fb4009533e8ff8f1450a5bcbc30f4242a1d34442221f72314bea1f5dc9c7f89"
|
checksum = "df099ccb16cd014ff054ac1bf392c67feeef57164b05c42f037cd40f5d4357f4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clipboard-win",
|
"clipboard-win",
|
||||||
"core-graphics 0.23.2",
|
"core-graphics 0.23.2",
|
||||||
@@ -270,9 +270,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "brotli"
|
name = "brotli"
|
||||||
version = "3.5.0"
|
version = "6.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d640d25bc63c50fb1f0b545ffd80207d2e10a4c965530809b40ba3386825c391"
|
checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"alloc-no-stdlib",
|
"alloc-no-stdlib",
|
||||||
"alloc-stdlib",
|
"alloc-stdlib",
|
||||||
@@ -281,9 +281,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "brotli-decompressor"
|
name = "brotli-decompressor"
|
||||||
version = "2.5.1"
|
version = "4.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f"
|
checksum = "9a45bd2e4095a8b518033b128020dd4a55aab1c0a381ba4404a472630f4bc362"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"alloc-no-stdlib",
|
"alloc-no-stdlib",
|
||||||
"alloc-stdlib",
|
"alloc-stdlib",
|
||||||
@@ -464,7 +464,7 @@ dependencies = [
|
|||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"block",
|
"block",
|
||||||
"cocoa-foundation",
|
"cocoa-foundation",
|
||||||
"core-foundation",
|
"core-foundation 0.9.4",
|
||||||
"core-graphics 0.22.3",
|
"core-graphics 0.22.3",
|
||||||
"foreign-types 0.3.2",
|
"foreign-types 0.3.2",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -479,7 +479,7 @@ checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"block",
|
"block",
|
||||||
"core-foundation",
|
"core-foundation 0.9.4",
|
||||||
"core-graphics-types",
|
"core-graphics-types",
|
||||||
"libc",
|
"libc",
|
||||||
"objc",
|
"objc",
|
||||||
@@ -529,10 +529,20 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "core-foundation-sys"
|
name = "core-foundation"
|
||||||
version = "0.8.6"
|
version = "0.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
|
checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63"
|
||||||
|
dependencies = [
|
||||||
|
"core-foundation-sys",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "core-foundation-sys"
|
||||||
|
version = "0.8.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "core-graphics"
|
name = "core-graphics"
|
||||||
@@ -541,7 +551,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb"
|
checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"core-foundation",
|
"core-foundation 0.9.4",
|
||||||
"core-graphics-types",
|
"core-graphics-types",
|
||||||
"foreign-types 0.3.2",
|
"foreign-types 0.3.2",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -554,7 +564,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081"
|
checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"core-foundation",
|
"core-foundation 0.9.4",
|
||||||
"core-graphics-types",
|
"core-graphics-types",
|
||||||
"foreign-types 0.5.0",
|
"foreign-types 0.5.0",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -567,7 +577,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf"
|
checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"core-foundation",
|
"core-foundation 0.9.4",
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -976,6 +986,15 @@ dependencies = [
|
|||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fluent-uri"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "17c704e9dbe1ddd863da1e6ff3567795087b1eb201ce80d8fa81162e1516500d"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.3.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fnv"
|
name = "fnv"
|
||||||
version = "1.0.7"
|
version = "1.0.7"
|
||||||
@@ -1971,14 +1990,39 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "keyring"
|
name = "json-patch"
|
||||||
version = "3.2.0"
|
version = "2.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "73b9af47ded4df3067484d7d45758ca2b36bd083bf6d024c2952bbd8af1cdaa4"
|
checksum = "5b1fb8864823fad91877e6caea0baca82e49e8db50f8e5c9f9a453e27d3330fc"
|
||||||
|
dependencies = [
|
||||||
|
"jsonptr",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jsonptr"
|
||||||
|
version = "0.4.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1c6e529149475ca0b2820835d3dce8fcc41c6b943ca608d32f35b449255e4627"
|
||||||
|
dependencies = [
|
||||||
|
"fluent-uri",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "keyring"
|
||||||
|
version = "3.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2f8fe839464d4e4b37d756d7e910063696af79a7e877282cb1825e4ec5f10833"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"dbus-secret-service",
|
"dbus-secret-service",
|
||||||
"security-framework",
|
"log",
|
||||||
|
"security-framework 2.11.1",
|
||||||
|
"security-framework 3.0.0",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2130,7 +2174,7 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mindwork-ai-studio"
|
name = "mindwork-ai-studio"
|
||||||
version = "0.9.12"
|
version = "0.9.17"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes",
|
"aes",
|
||||||
"arboard",
|
"arboard",
|
||||||
@@ -2216,7 +2260,7 @@ dependencies = [
|
|||||||
"openssl-probe",
|
"openssl-probe",
|
||||||
"openssl-sys",
|
"openssl-sys",
|
||||||
"schannel",
|
"schannel",
|
||||||
"security-framework",
|
"security-framework 2.11.1",
|
||||||
"security-framework-sys",
|
"security-framework-sys",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
]
|
]
|
||||||
@@ -3557,7 +3601,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
|
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.6.0",
|
"bitflags 2.6.0",
|
||||||
"core-foundation",
|
"core-foundation 0.9.4",
|
||||||
|
"core-foundation-sys",
|
||||||
|
"libc",
|
||||||
|
"security-framework-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "security-framework"
|
||||||
|
version = "3.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f9d0283c0a4a22a0f1b0e4edca251aa20b92fc96eaa09b84bec052f9415e9d71"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.6.0",
|
||||||
|
"core-foundation 0.10.0",
|
||||||
"core-foundation-sys",
|
"core-foundation-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"security-framework-sys",
|
"security-framework-sys",
|
||||||
@@ -3565,9 +3622,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "security-framework-sys"
|
name = "security-framework-sys"
|
||||||
version = "2.11.1"
|
version = "2.12.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf"
|
checksum = "ea4a292869320c0272d7bc55a5a6aafaff59b4f63404a003887b679a2e05b4b6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"core-foundation-sys",
|
"core-foundation-sys",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -3698,9 +3755,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serialize-to-javascript"
|
name = "serialize-to-javascript"
|
||||||
version = "0.1.1"
|
version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c9823f2d3b6a81d98228151fdeaf848206a7855a7a042bbf9bf870449a66cafb"
|
checksum = "04f3666a07a197cdb77cdf306c32be9b7f598d7060d50cfd4d5aa04bfd92f6c5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
@@ -3709,13 +3766,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serialize-to-javascript-impl"
|
name = "serialize-to-javascript-impl"
|
||||||
version = "0.1.1"
|
version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "74064874e9f6a15f04c1f3cb627902d0e6b410abbf36668afa873c61889f1763"
|
checksum = "772ee033c0916d670af7860b6e1ef7d658a4629a6d0b4c8c3e67f09b3765b75d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 1.0.109",
|
"syn 2.0.72",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3944,7 +4001,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
|
checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"core-foundation",
|
"core-foundation 0.9.4",
|
||||||
"system-configuration-sys",
|
"system-configuration-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -3994,7 +4051,7 @@ dependencies = [
|
|||||||
"cairo-rs",
|
"cairo-rs",
|
||||||
"cc",
|
"cc",
|
||||||
"cocoa",
|
"cocoa",
|
||||||
"core-foundation",
|
"core-foundation 0.9.4",
|
||||||
"core-graphics 0.22.3",
|
"core-graphics 0.22.3",
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
"dispatch",
|
"dispatch",
|
||||||
@@ -4061,12 +4118,12 @@ checksum = "4873307b7c257eddcb50c9bedf158eb669578359fb28428bef438fec8e6ba7c2"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri"
|
name = "tauri"
|
||||||
version = "1.7.1"
|
version = "1.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "336bc661a3f3250853fa83c6e5245449ed1c26dce5dcb28bdee7efedf6278806"
|
checksum = "1bf327e247698d3f39af8aa99401c9708384290d1f5c544bf5d251d44c2fea22"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64 0.21.7",
|
"base64 0.22.1",
|
||||||
"bytes",
|
"bytes",
|
||||||
"cocoa",
|
"cocoa",
|
||||||
"dirs-next",
|
"dirs-next",
|
||||||
@@ -4083,12 +4140,15 @@ dependencies = [
|
|||||||
"http 0.2.12",
|
"http 0.2.12",
|
||||||
"ignore",
|
"ignore",
|
||||||
"indexmap 1.9.3",
|
"indexmap 1.9.3",
|
||||||
|
"infer",
|
||||||
|
"log",
|
||||||
"minisign-verify",
|
"minisign-verify",
|
||||||
"objc",
|
"objc",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"open",
|
"open",
|
||||||
"os_pipe",
|
"os_pipe",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
|
"plist",
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
"raw-window-handle",
|
"raw-window-handle",
|
||||||
"regex",
|
"regex",
|
||||||
@@ -4128,7 +4188,7 @@ dependencies = [
|
|||||||
"cargo_toml",
|
"cargo_toml",
|
||||||
"dirs-next",
|
"dirs-next",
|
||||||
"heck 0.5.0",
|
"heck 0.5.0",
|
||||||
"json-patch",
|
"json-patch 1.4.0",
|
||||||
"semver",
|
"semver",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
@@ -4139,14 +4199,14 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri-codegen"
|
name = "tauri-codegen"
|
||||||
version = "1.4.4"
|
version = "1.4.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c1aed706708ff1200ec12de9cfbf2582b5d8ec05f6a7293911091effbd22036b"
|
checksum = "93a9e3f5cebf779a63bf24903e714ec91196c307d8249a0008b882424328bcda"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.21.7",
|
"base64 0.21.7",
|
||||||
"brotli",
|
"brotli",
|
||||||
"ico",
|
"ico",
|
||||||
"json-patch",
|
"json-patch 2.0.0",
|
||||||
"plist",
|
"plist",
|
||||||
"png",
|
"png",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
@@ -4165,9 +4225,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri-macros"
|
name = "tauri-macros"
|
||||||
version = "1.4.5"
|
version = "1.4.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b88f831d2973ae4f81a706a0004e67dac87f2e4439973bbe98efbd73825d8ede"
|
checksum = "d1d0e989f54fe06c5ef0875c5e19cf96453d099a0a774d5192ab47e80471cdab"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck 0.5.0",
|
"heck 0.5.0",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
@@ -4193,9 +4253,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri-runtime"
|
name = "tauri-runtime"
|
||||||
version = "0.14.4"
|
version = "0.14.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3068ed62b63dedc705558f4248c7ecbd5561f0f8050949859ea0db2326f26012"
|
checksum = "f33fda7d213e239077fad52e96c6b734cecedb30c2382118b64f94cb5103ff3a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gtk",
|
"gtk",
|
||||||
"http 0.2.12",
|
"http 0.2.12",
|
||||||
@@ -4214,9 +4274,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri-runtime-wry"
|
name = "tauri-runtime-wry"
|
||||||
version = "0.14.9"
|
version = "0.14.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d4c3db170233096aa30330feadcd895bf9317be97e624458560a20e814db7955"
|
checksum = "18c447dcd9b0f09c7dc4b752cc33e72788805bfd761fbda5692d30c48289efec"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cocoa",
|
"cocoa",
|
||||||
"gtk",
|
"gtk",
|
||||||
@@ -4234,9 +4294,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri-utils"
|
name = "tauri-utils"
|
||||||
version = "1.6.0"
|
version = "1.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2826db448309d382dac14d520f0c0a40839b87b57b977e59cf5f296b3ace6a93"
|
checksum = "83a0c939e88d82903a0a7dfb28388b12a3c03504d6bd6086550edaa3b6d8beaa"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"brotli",
|
"brotli",
|
||||||
"ctor",
|
"ctor",
|
||||||
@@ -4245,7 +4305,7 @@ dependencies = [
|
|||||||
"heck 0.5.0",
|
"heck 0.5.0",
|
||||||
"html5ever",
|
"html5ever",
|
||||||
"infer",
|
"infer",
|
||||||
"json-patch",
|
"json-patch 2.0.0",
|
||||||
"kuchikiki",
|
"kuchikiki",
|
||||||
"log",
|
"log",
|
||||||
"memchr",
|
"memchr",
|
||||||
@@ -4390,9 +4450,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.39.1"
|
version = "1.41.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d040ac2b29ab03b09d4129c2f5bbd012a3ac2f79d38ff506a4bf8dd34b0eac8a"
|
checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace",
|
"backtrace",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
|||||||
+5
-5
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "mindwork-ai-studio"
|
name = "mindwork-ai-studio"
|
||||||
version = "0.9.12"
|
version = "0.9.17"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "MindWork AI Studio"
|
description = "MindWork AI Studio"
|
||||||
authors = ["Thorsten Sommer"]
|
authors = ["Thorsten Sommer"]
|
||||||
@@ -9,13 +9,13 @@ authors = ["Thorsten Sommer"]
|
|||||||
tauri-build = { version = "1.5", features = [] }
|
tauri-build = { version = "1.5", features = [] }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tauri = { version = "1.7.1", features = [ "http-all", "updater", "shell-sidecar", "shell-open"] }
|
tauri = { version = "1.8.1", features = [ "http-all", "updater", "shell-sidecar", "shell-open"] }
|
||||||
tauri-plugin-window-state = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" }
|
tauri-plugin-window-state = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
keyring = { version = "3.2", features = ["apple-native", "windows-native", "sync-secret-service"] }
|
keyring = { version = "3.6", features = ["apple-native", "windows-native", "sync-secret-service"] }
|
||||||
arboard = "3.4.0"
|
arboard = "3.4.1"
|
||||||
tokio = { version = "1.39", features = ["rt", "rt-multi-thread", "macros"] }
|
tokio = { version = "1.41", features = ["rt", "rt-multi-thread", "macros"] }
|
||||||
flexi_logger = "0.29"
|
flexi_logger = "0.29"
|
||||||
log = { version = "0.4", features = ["kv"] }
|
log = { version = "0.4", features = ["kv"] }
|
||||||
once_cell = "1.19.0"
|
once_cell = "1.19.0"
|
||||||
|
|||||||
+6
-2
@@ -248,7 +248,7 @@ async fn main() {
|
|||||||
// parallel:
|
// parallel:
|
||||||
//
|
//
|
||||||
tauri::async_runtime::spawn(async move {
|
tauri::async_runtime::spawn(async move {
|
||||||
_ = rocket::custom(figment)
|
rocket::custom(figment)
|
||||||
.mount("/", routes![
|
.mount("/", routes![
|
||||||
dotnet_port, dotnet_ready, set_clipboard, check_for_update, install_update,
|
dotnet_port, dotnet_ready, set_clipboard, check_for_update, install_update,
|
||||||
get_secret, store_secret, delete_secret, get_data_directory, get_config_directory,
|
get_secret, store_secret, delete_secret, get_data_directory, get_config_directory,
|
||||||
@@ -966,7 +966,10 @@ fn get_secret(_token: APIToken, request: Json<RequestSecret>) -> Json<RequestedS
|
|||||||
},
|
},
|
||||||
|
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!(Source = "Secret Store"; "Failed to retrieve secret for '{service}' and user '{user_name}': {e}.");
|
if !request.is_trying {
|
||||||
|
error!(Source = "Secret Store"; "Failed to retrieve secret for '{service}' and user '{user_name}': {e}.");
|
||||||
|
}
|
||||||
|
|
||||||
Json(RequestedSecret {
|
Json(RequestedSecret {
|
||||||
success: false,
|
success: false,
|
||||||
secret: EncryptedText::new(String::from("")),
|
secret: EncryptedText::new(String::from("")),
|
||||||
@@ -980,6 +983,7 @@ fn get_secret(_token: APIToken, request: Json<RequestSecret>) -> Json<RequestedS
|
|||||||
struct RequestSecret {
|
struct RequestSecret {
|
||||||
destination: String,
|
destination: String,
|
||||||
user_name: String,
|
user_name: String,
|
||||||
|
is_trying: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
},
|
},
|
||||||
"package": {
|
"package": {
|
||||||
"productName": "MindWork AI Studio",
|
"productName": "MindWork AI Studio",
|
||||||
"version": "0.9.12"
|
"version": "0.9.17"
|
||||||
},
|
},
|
||||||
"tauri": {
|
"tauri": {
|
||||||
"allowlist": {
|
"allowlist": {
|
||||||
|
|||||||
Reference in new issue
Block a user