├── samples
├── output.xml
├── Mocale.Samples
│ ├── ViewModels
│ │ ├── BindingViewModel.cs
│ │ ├── BaseViewModel.cs
│ │ ├── ConverterViewModel.cs
│ │ ├── ParameterViewModel.cs
│ │ └── IntroductionPageViewModel.cs
│ ├── Resources
│ │ ├── Fonts
│ │ │ ├── OpenSans-Regular.ttf
│ │ │ └── OpenSans-Semibold.ttf
│ │ ├── AppIcon
│ │ │ ├── appicon.svg
│ │ │ └── appiconfg.svg
│ │ ├── Raw
│ │ │ └── AboutAssets.txt
│ │ ├── Splash
│ │ │ └── splash.svg
│ │ └── Styles
│ │ │ └── Colors.xaml
│ ├── Properties
│ │ ├── GlobalUsings.cs
│ │ ├── launchSettings.json
│ │ └── GlobalSuppression.cs
│ ├── AppShell.xaml.cs
│ ├── Platforms
│ │ ├── Android
│ │ │ ├── Resources
│ │ │ │ └── values
│ │ │ │ │ └── colors.xml
│ │ │ ├── MainApplication.cs
│ │ │ ├── MainActivity.cs
│ │ │ └── AndroidManifest.xml
│ │ ├── iOS
│ │ │ ├── AppDelegate.cs
│ │ │ ├── Program.cs
│ │ │ └── Info.plist
│ │ ├── MacCatalyst
│ │ │ ├── AppDelegate.cs
│ │ │ ├── Entitlements.plist
│ │ │ ├── Program.cs
│ │ │ └── Info.plist
│ │ ├── Windows
│ │ │ ├── App.xaml
│ │ │ ├── App.xaml.cs
│ │ │ ├── app.manifest
│ │ │ └── Package.appxmanifest
│ │ └── Tizen
│ │ │ ├── Main.cs
│ │ │ └── tizen-manifest.xml
│ ├── Pages
│ │ ├── ParameterPage.xaml.cs
│ │ ├── IntroductionPage.xaml.cs
│ │ ├── BasePage.cs
│ │ ├── BindingPage.xaml.cs
│ │ ├── ConverterPage.xaml.cs
│ │ ├── IntroductionPage.xaml
│ │ ├── CodePage.cs
│ │ └── ParameterPage.xaml
│ ├── App.xaml.cs
│ ├── App.xaml
│ ├── Enums
│ │ └── Cities.cs
│ ├── Converters
│ │ ├── CityDescriptionConverter.cs
│ │ └── LanguageEmojiConverter.cs
│ └── AppShell.xaml
├── Mocale.GeneratorSample
│ ├── Program.cs
│ ├── Locales
│ │ ├── fr-FR.json
│ │ └── en-GB.json
│ └── Mocale.GeneratorSample.csproj
└── Locales
│ ├── en-GB.json
│ └── fr-FR.json
├── .github
└── funding.yml
├── assets
├── mocale_icon_dark.png
├── mocale_icon_light.png
├── mocale_logo_color.png
├── mocale_icon_dark_small.png
├── Mocale_Main_Logo_800x600.jpg
├── mocale_icon_dark_rounded.png
├── mocale_icon_light_rounded.png
├── mocale_icon_light_small.png
└── Mocale_Inverted_Color_Crop.png
├── src
├── Mocale
│ ├── Properties
│ │ ├── AssemblyInfo.cs
│ │ ├── GlobalUsings.cs
│ │ └── GlobalSuppression.cs
│ ├── build
│ │ ├── Package.targets
│ │ └── Package.props
│ ├── Exceptions
│ │ ├── InitializationException.cs
│ │ └── MocaleException.cs
│ ├── Abstractions
│ │ ├── ILocalizationParser.cs
│ │ ├── IExternalFileNameHelper.cs
│ │ ├── IInternalTranslatorManager.cs
│ │ ├── IAppResourcesConfig.cs
│ │ ├── IExternalProviderConfiguration.cs
│ │ ├── IExternalLocalizationResult.cs
│ │ ├── IResourceFileDetails.cs
│ │ ├── ITranslationUpdater.cs
│ │ ├── ICurrentCultureManager.cs
│ │ ├── IEmbeddedResourcesConfig.cs
│ │ ├── IExternalLocalizationProvider.cs
│ │ ├── IInternalLocalizationProvider.cs
│ │ ├── IKeyConverter.cs
│ │ ├── IConfigurationManager.cs
│ │ ├── ILocalizationManager.cs
│ │ ├── ITranslationResolver.cs
│ │ ├── ILocalisationCacheManager.cs
│ │ ├── ITranslatorManager.cs
│ │ ├── IMocaleConfiguration.cs
│ │ └── ICacheUpdateManager.cs
│ ├── Models
│ │ ├── AppResourcesConfig.cs
│ │ ├── ExternalLocalizationResult.cs
│ │ ├── JsonResourceFileDetails.cs
│ │ ├── EmbeddedResourcesConfig.cs
│ │ ├── TranslationLoadResult.cs
│ │ ├── Localization.cs
│ │ ├── ResxResourceFileDetails.cs
│ │ ├── MocaleConfiguration.cs
│ │ └── LocalizeEnumBehavior.cs
│ ├── Constants.cs
│ ├── Enums
│ │ ├── LocaleResourceType.cs
│ │ └── TranslationSource.cs
│ ├── Extensions
│ │ ├── LocalizeEnumBehaviorExtension.cs
│ │ ├── UriExtension.cs
│ │ ├── TaskExtensions.cs
│ │ ├── DictionaryExtension.cs
│ │ ├── StringExtension.cs
│ │ ├── EnumExtensions.cs
│ │ ├── LocalizeExtension.cs
│ │ ├── TranslatorManagerExtensions.cs
│ │ └── LocalizeExtensionBase.cs
│ ├── Providers
│ │ ├── InactiveExternalLocalizationProvider.cs
│ │ └── AppResourceProvider.cs
│ ├── Managers
│ │ ├── ConfigurationManager.cs
│ │ └── CurrentCultureManager.cs
│ ├── MocaleInitializeService.cs
│ ├── Parsers
│ │ ├── JsonLocalizationParser.cs
│ │ └── ResxLocalizationParser.cs
│ ├── Helper
│ │ ├── EnumTranslationKeyHelper.cs
│ │ ├── ExternalJsonFileNameHelper.cs
│ │ └── ExternalResxFileNameHelper.cs
│ ├── Cache
│ │ └── InMemoryCacheManager.cs
│ ├── Mocale.csproj
│ ├── MocaleLocator.cs
│ └── MocaleBuilder.cs
├── Mocale.SourceGenerators
│ ├── build
│ │ ├── Package.targets
│ │ └── Package.props
│ ├── AnalyzerReleases.Unshipped.md
│ ├── Properties
│ │ └── launchSettings.json
│ ├── SourceProductionContextExtensions.cs
│ ├── AnalyzerReleases.Shipped.md
│ ├── Diagnostics.cs
│ └── Mocale.SourceGenerators.csproj
├── Mocale.Cache.SQLite
│ ├── Constants.cs
│ ├── Properties
│ │ ├── GlobalUsings.cs
│ │ └── GlobalSuppression.cs
│ ├── Abstractions
│ │ ├── IDatabasePathProvider.cs
│ │ ├── IDatabaseConnectionProvider.cs
│ │ ├── ISqliteConfig.cs
│ │ ├── ITranslationsRepository.cs
│ │ └── ICacheRepository.cs
│ ├── Entities
│ │ ├── UpdateHistoryItem.cs
│ │ └── TranslationItem.cs
│ ├── Models
│ │ └── SqliteConfig.cs
│ ├── Providers
│ │ ├── DatabasePathProvider.cs
│ │ └── DatabaseConnectionProvider.cs
│ ├── Repositories
│ │ ├── RepositoryBase.cs
│ │ └── CacheRepository.cs
│ ├── Mocale.Cache.SQLite.csproj
│ ├── Managers
│ │ ├── LocalisationCacheManager.cs
│ │ └── SqlCacheUpdateManager.cs
│ └── MocaleBuilderExtension.cs
├── Mocale.Providers.AWS.S3
│ ├── Properties
│ │ └── GlobalUsings.cs
│ ├── Abstractions
│ │ └── IBucketConfig.cs
│ ├── Models
│ │ └── BucketConfig.cs
│ ├── Mocale.Providers.AWS.S3.csproj
│ ├── MocaleBuilderExtension.cs
│ └── S3BucketProvider.cs
├── Mocale.Providers.GitHub.Raw
│ ├── Properties
│ │ ├── GlobalUsings.cs
│ │ └── GlobalSuppression.cs
│ ├── Helpers
│ │ └── RawUrlBuilder.cs
│ ├── Models
│ │ └── GithubRawConfig.cs
│ ├── Abstractions
│ │ └── IGithubRawConfig.cs
│ ├── Mocale.Providers.GitHub.Raw.csproj
│ └── MocaleBuilderExtension.cs
├── Mocale.Providers.Azure.Blob
│ ├── Properties
│ │ ├── GlobalUsings.cs
│ │ └── GlobalSuppression.cs
│ ├── Models
│ │ ├── BlobResourceInfo.cs
│ │ └── BlobStorageConfig.cs
│ ├── Abstractions
│ │ ├── IBlobResourceLocator.cs
│ │ └── IBlobStorageConfig.cs
│ ├── Mocale.Providers.Azure.Blob.csproj
│ └── MocaleBuilderExtension.cs
├── Mocale.Testing
│ ├── Mocale.Testing.csproj
│ ├── MocaleLocatorHelper.cs
│ └── Extensions
│ │ └── DictionaryExtension.cs
└── directory.build.props
├── global.json
├── tests
├── Mocale.UnitTests
│ ├── Snapshots
│ │ ├── Locales
│ │ │ └── en-GB.json
│ │ ├── TranslationKeySourceGeneratorSnapshotTests.GeneratesTranslationKeys_WhenNoAdditionalFiles_ShouldGenerateNoKeys#MocaleTranslationKeys.g.verified.cs
│ │ ├── TranslationKeySourceGeneratorSnapshotTests.GeneratesTranslationKeys_WhenNoAdditionalFiles_ShouldGenerateNoKeys.verified.txt
│ │ ├── TranslationKeySourceGeneratorSnapshotTests.GeneratesTranslationKeys_WhenSingleFile_ShouldGenerateCorrectly#MocaleTranslationKeys.g.verified.cs
│ │ ├── TranslationKeySourceGeneratorSnapshotTests.GeneratesTranslationKeys_WhenMultipleFilesButAllTheSameKeys_ShouldContainOnlyUniqueKeys#MocaleTranslationKeys.g.verified.cs
│ │ └── TranslationKeySourceGeneratorSnapshotTests.GeneratesTranslationKeys_WhenMultipleFilesButDifferentKeys_ShouldContainOnlyUniqueKeys#MocaleTranslationKeys.g.verified.cs
│ ├── TestUtils
│ │ ├── TranslationKeySourceGeneratorSnapshotTests.GeneratesTranslationKeys_WhenKeysContainIllegalCharacters_ShouldGenerateSanitizedFields#MocaleTranslationKeys.g.verified.cs
│ │ ├── TranslationKeySourceGeneratorSnapshotTests.GeneratesTranslationKeys_WhenNoAdditionalFiles_ShouldGenerateNoKeys#MocaleTranslationKeys.g.verified.cs
│ │ ├── TestAdditionalText.cs
│ │ ├── TranslationKeySourceGeneratorSnapshotTests.GeneratesTranslationKeys_WhenNoAdditionalFiles_ShouldGenerateNoKeys.verified.txt
│ │ ├── TranslationKeySourceGeneratorSnapshotTests.GeneratesTranslationKeys_WhenSingleFile_ShouldGenerateCorrectly#MocaleTranslationKeys.g.verified.cs
│ │ ├── TranslationKeySourceGeneratorSnapshotTests.GeneratesTranslationKeys_WhenKeysContainIllegalCharacters_ShouldGenerateSanitizedFields#MocaleTranslationKeys.g.received.cs
│ │ ├── TranslationKeySourceGeneratorSnapshotTests.GeneratesTranslationKeys_WhenMultipleFilesButAllTheSameKeys_ShouldContainOnlyUniqueKeys#MocaleTranslationKeys.g.verified.cs
│ │ ├── TranslationKeySourceGeneratorSnapshotTests.GeneratesTranslationKeys_WhenMultipleFilesButDifferentKeys_ShouldContainOnlyUniqueKeys#MocaleTranslationKeys.g.verified.cs
│ │ └── ServiceCollectionAssertions.cs
│ ├── Properties
│ │ ├── GlobalUsings.cs
│ │ └── GlobalSuppressions.cs
│ ├── MocaleTestInitializer.cs
│ ├── .editorconfig
│ ├── Fixtures
│ │ ├── MocaleLocatorFixture.cs
│ │ ├── FixtureBase.cs
│ │ └── ControlsFixtureBase.cs
│ ├── Collections
│ │ ├── CollectionNames.cs
│ │ └── CollectionDefinitions.cs
│ ├── Mocale.UnitTests.csproj.DotSettings
│ ├── Resources
│ │ ├── en-GB.json
│ │ ├── Misc
│ │ │ ├── TestFile.json
│ │ │ └── RandomFile.txt
│ │ ├── Invalid
│ │ │ └── en-GB.json
│ │ └── Resx
│ │ │ ├── TestResources.fr-fr.resx
│ │ │ ├── TestResources.resx
│ │ │ └── TestResources.Designer.cs
│ ├── MocaleLocatorTests.cs
│ ├── Providers
│ │ └── InactiveExternalLocalizationProviderTests.cs
│ ├── Extensions
│ │ ├── StringExtensionTests.cs
│ │ ├── UriExtensionTests.cs
│ │ ├── LocalizeEnumBehaviorExtensionTests.cs
│ │ └── EnumExtensionsTests.cs
│ ├── Testing
│ │ └── MocaleLocatorHelperTests.cs
│ ├── Helpers
│ │ ├── RawUrlBuilderTests.cs
│ │ └── ExternalJsonFileNameHelperTests.cs
│ └── MocaleInitializeServiceTests.cs
└── directory.packages.props
├── nuget.config
├── version.json
├── LICENSE
├── directory.build.props
└── directory.packages.props
/samples/output.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.github/funding.yml:
--------------------------------------------------------------------------------
1 | github: axemasta
2 | buy_me_a_coffee: axemasta
3 |
--------------------------------------------------------------------------------
/assets/mocale_icon_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Axemasta/Mocale/HEAD/assets/mocale_icon_dark.png
--------------------------------------------------------------------------------
/assets/mocale_icon_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Axemasta/Mocale/HEAD/assets/mocale_icon_light.png
--------------------------------------------------------------------------------
/assets/mocale_logo_color.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Axemasta/Mocale/HEAD/assets/mocale_logo_color.png
--------------------------------------------------------------------------------
/assets/mocale_icon_dark_small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Axemasta/Mocale/HEAD/assets/mocale_icon_dark_small.png
--------------------------------------------------------------------------------
/assets/Mocale_Main_Logo_800x600.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Axemasta/Mocale/HEAD/assets/Mocale_Main_Logo_800x600.jpg
--------------------------------------------------------------------------------
/assets/mocale_icon_dark_rounded.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Axemasta/Mocale/HEAD/assets/mocale_icon_dark_rounded.png
--------------------------------------------------------------------------------
/assets/mocale_icon_light_rounded.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Axemasta/Mocale/HEAD/assets/mocale_icon_light_rounded.png
--------------------------------------------------------------------------------
/assets/mocale_icon_light_small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Axemasta/Mocale/HEAD/assets/mocale_icon_light_small.png
--------------------------------------------------------------------------------
/assets/Mocale_Inverted_Color_Crop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Axemasta/Mocale/HEAD/assets/Mocale_Inverted_Color_Crop.png
--------------------------------------------------------------------------------
/src/Mocale/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | [assembly: XmlnsDefinition("http://axemasta.com/schemas/2022/mocale", "Mocale.Extensions")]
2 |
--------------------------------------------------------------------------------
/global.json:
--------------------------------------------------------------------------------
1 | {
2 | "sdk": {
3 | "version": "9.0.200",
4 | "rollForward": "latestFeature",
5 | "allowPrerelease": false
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/samples/Mocale.Samples/ViewModels/BindingViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Samples.ViewModels;
2 |
3 | public sealed partial class BindingViewModel : BaseViewModel;
4 |
--------------------------------------------------------------------------------
/src/Mocale/build/Package.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/samples/Mocale.Samples/Resources/Fonts/OpenSans-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Axemasta/Mocale/HEAD/samples/Mocale.Samples/Resources/Fonts/OpenSans-Regular.ttf
--------------------------------------------------------------------------------
/samples/Mocale.Samples/Resources/Fonts/OpenSans-Semibold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Axemasta/Mocale/HEAD/samples/Mocale.Samples/Resources/Fonts/OpenSans-Semibold.ttf
--------------------------------------------------------------------------------
/src/Mocale/Exceptions/InitializationException.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Exceptions;
2 |
3 | internal class InitializationException(string message) : MocaleException(message);
4 |
--------------------------------------------------------------------------------
/src/Mocale.SourceGenerators/build/Package.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/samples/Mocale.GeneratorSample/Program.cs:
--------------------------------------------------------------------------------
1 | using Mocale.Translations;
2 |
3 | Console.WriteLine("Debug Source Generators Project");
4 | Console.WriteLine(TranslationKeys.MocaleTitle);
5 |
--------------------------------------------------------------------------------
/samples/Mocale.Samples/Properties/GlobalUsings.cs:
--------------------------------------------------------------------------------
1 | global using Mocale.Abstractions;
2 | global using CommunityToolkit.Mvvm.ComponentModel;
3 | global using Mocale.Samples.ObjectModel;
4 |
--------------------------------------------------------------------------------
/tests/Mocale.UnitTests/Snapshots/Locales/en-GB.json:
--------------------------------------------------------------------------------
1 | {
2 | "KeyOne": "Value One",
3 | "Key_Two": "Value Two",
4 | "Key@!_/Three": "Value Three",
5 | "Key.Four": "Value Four"
6 | }
7 |
--------------------------------------------------------------------------------
/src/Mocale.Cache.SQLite/Constants.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Cache.SQLite;
2 |
3 | internal static class Constants
4 | {
5 | public const string DatabaseFileName = "Mocale.db";
6 | }
7 |
8 |
--------------------------------------------------------------------------------
/tests/Mocale.UnitTests/TestUtils/TranslationKeySourceGeneratorSnapshotTests.GeneratesTranslationKeys_WhenKeysContainIllegalCharacters_ShouldGenerateSanitizedFields#MocaleTranslationKeys.g.verified.cs:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/samples/Mocale.Samples/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "profiles": {
3 | "Windows Machine": {
4 | "commandName": "MsixPackage",
5 | "nativeDebugging": false
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/samples/Mocale.Samples/ViewModels/BaseViewModel.cs:
--------------------------------------------------------------------------------
1 | using CommunityToolkit.Mvvm.ComponentModel;
2 |
3 | namespace Mocale.Samples.ViewModels;
4 | public partial class BaseViewModel : ObservableObject
5 | {
6 | }
7 |
--------------------------------------------------------------------------------
/samples/Mocale.Samples/AppShell.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Samples;
2 |
3 | public partial class AppShell : Shell
4 | {
5 | public AppShell()
6 | {
7 | InitializeComponent();
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/Mocale.SourceGenerators/AnalyzerReleases.Unshipped.md:
--------------------------------------------------------------------------------
1 | ; Unshipped analyzer release
2 | ; https://github.com/dotnet/roslyn-analyzers/blob/main/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md
3 |
--------------------------------------------------------------------------------
/src/Mocale/Abstractions/ILocalizationParser.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Abstractions;
2 |
3 | internal interface ILocalizationParser
4 | {
5 | Dictionary? ParseLocalizationStream(Stream resourceStream);
6 | }
7 |
--------------------------------------------------------------------------------
/src/Mocale/Properties/GlobalUsings.cs:
--------------------------------------------------------------------------------
1 | global using Mocale.Abstractions;
2 | global using Mocale.Enums;
3 | global using Mocale.Extensions;
4 | global using Mocale.Models;
5 | global using Microsoft.Extensions.Logging;
6 |
--------------------------------------------------------------------------------
/src/Mocale/build/Package.props:
--------------------------------------------------------------------------------
1 |
2 |
3 | Resources\Locales\*.json
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/tests/Mocale.UnitTests/Properties/GlobalUsings.cs:
--------------------------------------------------------------------------------
1 | global using Xunit;
2 | global using FluentAssertions;
3 | global using Moq;
4 | global using Mocale.UnitTests.TestUtils;
5 | global using Mocale.UnitTests.Fixtures;
6 |
--------------------------------------------------------------------------------
/nuget.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/Mocale.SourceGenerators/build/Package.props:
--------------------------------------------------------------------------------
1 |
2 |
3 | Resources\Locales\*.json
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/Mocale/Abstractions/IExternalFileNameHelper.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 |
3 | namespace Mocale.Abstractions;
4 |
5 | internal interface IExternalFileNameHelper
6 | {
7 | string GetExpectedFileName(CultureInfo culture);
8 | }
9 |
--------------------------------------------------------------------------------
/src/Mocale/Models/AppResourcesConfig.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Models;
2 |
3 | ///
4 | public class AppResourcesConfig : IAppResourcesConfig
5 | {
6 | ///
7 | public Type? AppResourcesType { get; set; }
8 | }
9 |
--------------------------------------------------------------------------------
/src/Mocale.Cache.SQLite/Properties/GlobalUsings.cs:
--------------------------------------------------------------------------------
1 | global using Mocale.Cache.SQLite.Abstractions;
2 | global using Mocale.Cache.SQLite.Models;
3 | global using Ardalis.GuardClauses;
4 | global using SQLite;
5 | global using Mocale.Cache.SQLite.Entities;
6 |
--------------------------------------------------------------------------------
/src/Mocale/Abstractions/IInternalTranslatorManager.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Abstractions;
2 |
3 | internal interface IInternalTranslatorManager : ITranslatorManager, ITranslationUpdater
4 | {
5 | void RaisePropertyChanged(string? propertyName = null);
6 | }
7 |
--------------------------------------------------------------------------------
/src/Mocale.Providers.AWS.S3/Properties/GlobalUsings.cs:
--------------------------------------------------------------------------------
1 | global using Mocale.Providers.AWS.S3.Abstractions;
2 | global using Mocale.Providers.AWS.S3.Models;
3 | global using Mocale.Abstractions;
4 | global using Mocale.Models;
5 | global using System.Globalization;
6 |
--------------------------------------------------------------------------------
/src/Mocale.SourceGenerators/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "profiles": {
3 | "Debug": {
4 | "commandName": "DebugRoslynComponent",
5 | "targetProject": "..\\..\\samples\\Mocale.GeneratorSample\\Mocale.GeneratorSample.csproj"
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/samples/Mocale.Samples/Resources/AppIcon/appicon.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/Mocale.Providers.GitHub.Raw/Properties/GlobalUsings.cs:
--------------------------------------------------------------------------------
1 | global using Mocale.Abstractions;
2 | global using Mocale.Models;
3 | global using Mocale.Providers.GitHub.Raw.Abstractions;
4 | global using Mocale.Providers.GitHub.Raw.Models;
5 | global using Microsoft.Extensions.Logging;
6 |
--------------------------------------------------------------------------------
/samples/Mocale.Samples/Platforms/Android/Resources/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #512BD4
4 | #2B0B98
5 | #2B0B98
6 |
7 |
--------------------------------------------------------------------------------
/samples/Locales/en-GB.json:
--------------------------------------------------------------------------------
1 | {
2 | "CurrentLocaleName": "English",
3 | "LocalizationCurrentProviderIs": "GR_The current localization provider is:",
4 | "LocalizationProviderName": "GR_Json",
5 | "MocaleDescription": "GR_Localization framework for .NET Maui",
6 | "MocaleTitle": "GR_Mocale"
7 | }
8 |
--------------------------------------------------------------------------------
/src/Mocale/Models/ExternalLocalizationResult.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Models;
2 |
3 | internal class ExternalLocalizationResult : IExternalLocalizationResult
4 | {
5 | public required bool Success { get; set; }
6 |
7 | public Dictionary? Localizations { get; set; }
8 | }
9 |
--------------------------------------------------------------------------------
/samples/Locales/fr-FR.json:
--------------------------------------------------------------------------------
1 | {
2 | "CurrentLocaleName": "French",
3 | "LocalizationCurrentProviderIs": "GR_Le fournisseur de localisation actuel est:",
4 | "LocalizationProviderName": "GR_Json",
5 | "MocaleDescription": "GR_Framework de localisation pour .NET Maui",
6 | "MocaleTitle": "GR_Mocale"
7 | }
8 |
--------------------------------------------------------------------------------
/tests/Mocale.UnitTests/Snapshots/TranslationKeySourceGeneratorSnapshotTests.GeneratesTranslationKeys_WhenNoAdditionalFiles_ShouldGenerateNoKeys#MocaleTranslationKeys.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: MocaleTranslationKeys.g.cs
2 | namespace Mocale.Translations
3 | {
4 | public static class TranslationKeys
5 | {
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/tests/Mocale.UnitTests/TestUtils/TranslationKeySourceGeneratorSnapshotTests.GeneratesTranslationKeys_WhenNoAdditionalFiles_ShouldGenerateNoKeys#MocaleTranslationKeys.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: MocaleTranslationKeys.g.cs
2 | namespace Mocale.Translations
3 | {
4 | public static class TranslationKeys
5 | {
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/samples/Mocale.GeneratorSample/Locales/fr-FR.json:
--------------------------------------------------------------------------------
1 | {
2 | "CurrentLocaleName": "French",
3 | "LocalizationCurrentProviderIs": "Le fournisseur de localisation actuel est:",
4 | "LocalizationProviderName": "Json",
5 | "MocaleDescription": "Framework de localisation pour .NET Maui",
6 | "MocaleTitle": "Mocale"
7 | }
8 |
--------------------------------------------------------------------------------
/tests/Mocale.UnitTests/MocaleTestInitializer.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.CompilerServices;
2 |
3 | namespace Mocale.UnitTests;
4 |
5 | public static class MocaleTestInitializer
6 | {
7 | [ModuleInitializer]
8 | public static void Init()
9 | {
10 | VerifySourceGenerators.Initialize();
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/version.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
3 | "version": "1.0-pre",
4 | "assemblyVersion": {
5 | "precision": "revision"
6 | },
7 | "publicReleaseRefSpec": [
8 | "^refs/heads/main$"
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/samples/Mocale.Samples/Platforms/iOS/AppDelegate.cs:
--------------------------------------------------------------------------------
1 | using Foundation;
2 | namespace Mocale.Samples;
3 |
4 | [Register("AppDelegate")]
5 | public class AppDelegate : MauiUIApplicationDelegate
6 | {
7 | protected override MauiApp CreateMauiApp()
8 | {
9 | return MauiProgram.CreateMauiApp();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/samples/Mocale.Samples/Platforms/MacCatalyst/AppDelegate.cs:
--------------------------------------------------------------------------------
1 | using Foundation;
2 | namespace Mocale.Samples;
3 |
4 | [Register("AppDelegate")]
5 | public class AppDelegate : MauiUIApplicationDelegate
6 | {
7 | protected override MauiApp CreateMauiApp()
8 | {
9 | return MauiProgram.CreateMauiApp();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/samples/Mocale.Samples/Platforms/MacCatalyst/Entitlements.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/samples/Mocale.Samples/Platforms/Windows/App.xaml:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/src/Mocale/Abstractions/IAppResourcesConfig.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Abstractions;
2 |
3 | ///
4 | /// Configuration For App Resources
5 | ///
6 | public interface IAppResourcesConfig
7 | {
8 | ///
9 | /// The type for the app resources
10 | ///
11 | Type? AppResourcesType { get; }
12 | }
13 |
--------------------------------------------------------------------------------
/samples/Mocale.Samples/Pages/ParameterPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using Mocale.Samples.ViewModels;
2 |
3 | namespace Mocale.Samples.Pages;
4 |
5 | public partial class ParameterPage : BasePage
6 | {
7 | public ParameterPage(ParameterViewModel viewModel)
8 | : base(viewModel)
9 | {
10 | InitializeComponent();
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Mocale/Exceptions/MocaleException.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Exceptions;
2 |
3 | internal class MocaleException : Exception
4 | {
5 | public MocaleException(string message)
6 | : base(message)
7 | {
8 | }
9 |
10 | public MocaleException(string message, Exception inner)
11 | : base(message, inner)
12 | {
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/Mocale/Models/JsonResourceFileDetails.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Models;
2 |
3 | ///
4 | public class JsonResourceFileDetails : IResourceFileDetails
5 | {
6 | ///
7 | public LocaleResourceType ResourceType { get; } = LocaleResourceType.Json;
8 | ///
9 | public string? VersionPrefix { get; set; }
10 | }
11 |
--------------------------------------------------------------------------------
/src/Mocale/Constants.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale;
2 |
3 | internal class Constants
4 | {
5 | public const string LastUsedCultureKey = "Mocale_LastUsedCulture";
6 |
7 | public const string LastUpdatedExternalResourceKey = "Mocale_LastUpdatedExternalResources";
8 |
9 | public const string UpdateCacheStorageKey = "Mocale_UpdateCacheStorage";
10 | }
11 |
--------------------------------------------------------------------------------
/src/Mocale/Enums/LocaleResourceType.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Enums;
2 |
3 | ///
4 | /// Locale Resource Type
5 | ///
6 | public enum LocaleResourceType
7 | {
8 | ///
9 | /// Resx File
10 | ///
11 | Resx = 0,
12 |
13 | ///
14 | /// Json File
15 | ///
16 | Json = 1,
17 | }
18 |
--------------------------------------------------------------------------------
/samples/Mocale.Samples/App.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Samples;
2 |
3 | public partial class App : Application
4 | {
5 | public App()
6 | {
7 | InitializeComponent();
8 | }
9 |
10 | protected override Window CreateWindow(IActivationState activationState)
11 | {
12 | return new Window(new AppShell());
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/Mocale.Providers.AWS.S3/Abstractions/IBucketConfig.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Providers.AWS.S3.Abstractions;
2 |
3 | ///
4 | /// S3 Bucket Config
5 | ///
6 | public interface IBucketConfig : IExternalProviderConfiguration
7 | {
8 | ///
9 | /// Uri for the blob container
10 | ///
11 | Uri? BucketUri { get; }
12 | }
13 |
--------------------------------------------------------------------------------
/tests/Mocale.UnitTests/.editorconfig:
--------------------------------------------------------------------------------
1 | ###############################
2 | # Core EditorConfig Options #
3 | ###############################
4 |
5 | # Csharp files
6 | [*.{cs,vb}]
7 | dotnet_diagnostic.CA1309.severity = none
8 | dotnet_diagnostic.CA1861.severity = none
9 |
10 | # Resharper
11 | [resharper_]
12 | resharper_structured_message_template_problem_highlighting = none
--------------------------------------------------------------------------------
/samples/Mocale.Samples/Pages/IntroductionPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using Mocale.Samples.ViewModels;
2 | namespace Mocale.Samples.Pages;
3 |
4 | public partial class IntroductionPage : BasePage
5 | {
6 | public IntroductionPage(IntroductionPageViewModel viewModel)
7 | : base(viewModel)
8 | {
9 |
10 | InitializeComponent();
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/tests/Mocale.UnitTests/Fixtures/MocaleLocatorFixture.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.UnitTests.Fixtures;
2 |
3 | public class MocaleLocatorFixture : IDisposable
4 | {
5 | public virtual void Dispose()
6 | {
7 | MocaleLocator.MocaleConfiguration = null;
8 | MocaleLocator.TranslatorManager = null;
9 | GC.SuppressFinalize(this);
10 | }
11 | }
12 |
13 |
--------------------------------------------------------------------------------
/tests/Mocale.UnitTests/Collections/CollectionNames.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.UnitTests.Collections;
2 |
3 | public static class CollectionNames
4 | {
5 | public const string MocaleLocatorTests = "MocaleLocatorCollection";
6 |
7 | public const string ThreadCultureTests = "ThreadCultureCollection";
8 |
9 | public const string TestingTests = "TestingCollection";
10 | }
11 |
--------------------------------------------------------------------------------
/src/Mocale.Providers.AWS.S3/Models/BucketConfig.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Providers.AWS.S3.Models;
2 |
3 | ///
4 | public class BucketConfig : IBucketConfig
5 | {
6 | ///
7 | public Uri? BucketUri { get; set; }
8 |
9 | ///
10 | public IResourceFileDetails ResourceFileDetails { get; set; } = new JsonResourceFileDetails();
11 | }
12 |
--------------------------------------------------------------------------------
/samples/Mocale.Samples/Pages/BasePage.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Samples.Pages;
2 |
3 | public abstract class BasePage : ContentPage
4 | where TViewModel : ObservableObject
5 | {
6 | protected BasePage(TViewModel viewModel)
7 | {
8 | base.BindingContext = viewModel;
9 | }
10 |
11 | public new TViewModel BindingContext => (TViewModel)base.BindingContext;
12 | }
13 |
--------------------------------------------------------------------------------
/samples/Mocale.Samples/Pages/BindingPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using Mocale.Extensions;
2 | using Mocale.Translations;
3 |
4 | namespace Mocale.Samples.Pages;
5 |
6 | public partial class BindingPage : ContentPage
7 | {
8 | public BindingPage()
9 | {
10 | InitializeComponent();
11 |
12 | Label.SetTranslation(Label.TextProperty, TranslationKeys.BindingPageCodeBehindLabelKey);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/Mocale.Cache.SQLite/Abstractions/IDatabasePathProvider.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Cache.SQLite.Abstractions;
2 |
3 | ///
4 | /// Database Path Provider
5 | ///
6 | public interface IDatabasePathProvider
7 | {
8 | ///
9 | /// Get SQLite database path on the device
10 | ///
11 | ///
12 | string GetDatabasePath();
13 | }
14 |
--------------------------------------------------------------------------------
/samples/Mocale.Samples/Platforms/Android/MainApplication.cs:
--------------------------------------------------------------------------------
1 | using Android.App;
2 | using Android.Runtime;
3 | namespace Mocale.Samples;
4 |
5 | [Application]
6 | public class MainApplication(IntPtr handle, JniHandleOwnership ownership) : MauiApplication(handle, ownership)
7 | {
8 | protected override MauiApp CreateMauiApp()
9 | {
10 | return MauiProgram.CreateMauiApp();
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/samples/Mocale.GeneratorSample/Locales/en-GB.json:
--------------------------------------------------------------------------------
1 | {
2 | "CurrentLocaleName": "English",
3 | "LocalizationCurrentProviderIs": "The current localization provider is:",
4 | "LocalizationProviderName": "Json",
5 | "MocaleDescription": "Localization framework for .NET Maui",
6 | "MocaleTitle": "Mocale",
7 | "nonCamelTitle": "ThisIsCamel",
8 | "Hello World": "Hello World",
9 | "Acme.Com": "www.acme.com"
10 | }
11 |
--------------------------------------------------------------------------------
/samples/Mocale.Samples/Platforms/Tizen/Main.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.Maui;
3 | using Microsoft.Maui.Hosting;
4 |
5 | namespace Mocale.Samples;
6 |
7 | class Program : MauiApplication
8 | {
9 | protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
10 |
11 | static void Main(string[] args)
12 | {
13 | var app = new Program();
14 | app.Run(args);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Mocale/Abstractions/IExternalProviderConfiguration.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Abstractions;
2 |
3 | ///
4 | /// External Provider Configuration
5 | ///
6 | public interface IExternalProviderConfiguration
7 | {
8 | ///
9 | /// Details about the resource files returned by the external provider
10 | ///
11 | IResourceFileDetails ResourceFileDetails { get; }
12 | }
13 |
14 |
--------------------------------------------------------------------------------
/src/Mocale.Cache.SQLite/Entities/UpdateHistoryItem.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Cache.SQLite.Entities;
2 |
3 | #nullable disable
4 |
5 | [Table("UpdateHistory")]
6 | internal class UpdateHistoryItem
7 | {
8 | [PrimaryKey]
9 | [AutoIncrement]
10 | public int Id { get; set; }
11 |
12 | public string CultureName { get; set; }
13 |
14 | public DateTime LastUpdated { get; set; }
15 | }
16 |
17 | #nullable enable
18 |
--------------------------------------------------------------------------------
/src/Mocale.Cache.SQLite/Abstractions/IDatabaseConnectionProvider.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Cache.SQLite.Abstractions;
2 |
3 | ///
4 | /// SQLite Database Connection Provider
5 | ///
6 | public interface IDatabaseConnectionProvider
7 | {
8 | ///
9 | /// Get connection to the sqlite database
10 | ///
11 | ///
12 | SQLiteConnection GetDatabaseConnection();
13 | }
14 |
--------------------------------------------------------------------------------
/src/Mocale.Providers.Azure.Blob/Properties/GlobalUsings.cs:
--------------------------------------------------------------------------------
1 | global using Mocale.Abstractions;
2 | global using Mocale.Models;
3 | global using Mocale.Providers.Azure.Blob.Abstractions;
4 | global using Mocale.Providers.Azure.Blob.Models;
5 | global using Microsoft.Extensions.Logging;
6 | global using System.Globalization;
7 | global using Ardalis.GuardClauses;
8 | global using Azure.Storage.Blobs;
9 | global using Azure.Storage.Blobs.Models;
10 |
--------------------------------------------------------------------------------
/samples/Mocale.Samples/Platforms/Android/MainActivity.cs:
--------------------------------------------------------------------------------
1 | using Android.App;
2 | using Android.Content.PM;
3 | namespace Mocale.Samples;
4 |
5 | [Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
6 | public class MainActivity : MauiAppCompatActivity
7 | {
8 | }
9 |
--------------------------------------------------------------------------------
/samples/Mocale.Samples/Platforms/iOS/Program.cs:
--------------------------------------------------------------------------------
1 | using UIKit;
2 | namespace Mocale.Samples;
3 |
4 | public class Program
5 | {
6 | // This is the main entry point of the application.
7 | private static void Main(string[] args)
8 | {
9 | // if you want to use a different Application Delegate class from "AppDelegate"
10 | // you can specify it here.
11 | UIApplication.Main(args, null, typeof(AppDelegate));
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/Mocale.SourceGenerators/SourceProductionContextExtensions.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.CodeAnalysis;
2 | namespace Mocale.SourceGenerators;
3 |
4 | internal static class SourceProductionContextExtensions
5 | {
6 | public static void Report(this SourceProductionContext context, DiagnosticDescriptor diagnosticDescriptor, params object?[]? args)
7 | {
8 | context.ReportDiagnostic(Diagnostic.Create(diagnosticDescriptor, null, args));
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/Mocale.Cache.SQLite/Entities/TranslationItem.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Cache.SQLite.Entities;
2 |
3 | #nullable disable
4 |
5 | [Table("Translations")]
6 | internal class TranslationItem
7 | {
8 | [PrimaryKey]
9 | [AutoIncrement]
10 | public int Id { get; set; }
11 |
12 | public string CultureName { get; set; }
13 |
14 | public string Key { get; set; }
15 |
16 | public string Value { get; set; }
17 | }
18 |
19 | #nullable enable
20 |
--------------------------------------------------------------------------------
/tests/Mocale.UnitTests/TestUtils/TestAdditionalText.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.CodeAnalysis;
2 | using Microsoft.CodeAnalysis.Text;
3 |
4 | namespace Mocale.UnitTests.TestUtils;
5 |
6 | public class TestAdditionalText(string path, string content) : AdditionalText
7 | {
8 | public override string Path => path;
9 |
10 | public override SourceText GetText(CancellationToken cancellationToken = default)
11 | {
12 | return SourceText.From(content);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/samples/Mocale.Samples/Platforms/MacCatalyst/Program.cs:
--------------------------------------------------------------------------------
1 | using UIKit;
2 | namespace Mocale.Samples;
3 |
4 | public class Program
5 | {
6 | // This is the main entry point of the application.
7 | private static void Main(string[] args)
8 | {
9 | // if you want to use a different Application Delegate class from "AppDelegate"
10 | // you can specify it here.
11 | UIApplication.Main(args, null, typeof(AppDelegate));
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/samples/Mocale.Samples/Platforms/Android/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/Mocale/Extensions/LocalizeEnumBehaviorExtension.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Extensions;
2 |
3 | internal static class LocalizeEnumBehaviorExtension
4 | {
5 | public static bool ShouldLocalizeEnum(this LocalizeEnumBehavior localizeEnumBehavior, Enum enumValue)
6 | {
7 | return localizeEnumBehavior.OverrideRules.TryGetValue(enumValue.GetType(), out var rule)
8 | ? rule.UseAttribute
9 | : localizeEnumBehavior.UseAttribute;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/Mocale/Models/EmbeddedResourcesConfig.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | namespace Mocale.Models;
3 |
4 | ///
5 | public class EmbeddedResourcesConfig : IEmbeddedResourcesConfig
6 | {
7 | ///
8 | public string ResourcesPath { get; set; } = "Locales";
9 |
10 | ///
11 | public Assembly? ResourcesAssembly { get; set; }
12 |
13 | ///
14 | public bool UseResourceFolder { get; set; } = true;
15 | }
16 |
--------------------------------------------------------------------------------
/tests/Mocale.UnitTests/Mocale.UnitTests.csproj.DotSettings:
--------------------------------------------------------------------------------
1 |
5 | DO_NOT_SHOW
7 |
8 |
--------------------------------------------------------------------------------
/src/Mocale/Properties/GlobalSuppression.cs:
--------------------------------------------------------------------------------
1 | // This file is used by Code Analysis to maintain SuppressMessage attributes that are applied to
2 | // this project. Project-level suppressions either have no target or are given a specific target and
3 | // scoped to a namespace, type, member, etc.
4 |
5 | using System.Diagnostics.CodeAnalysis;
6 | [assembly: SuppressMessage("Performance", "CA1848:Use the LoggerMessage delegates", Justification = "This message is annoying, why provide methods we can't use?")]
7 |
--------------------------------------------------------------------------------
/src/Mocale.Cache.SQLite/Models/SqliteConfig.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Cache.SQLite.Models;
2 |
3 | ///
4 | public class SqliteConfig : ISqliteConfig
5 | {
6 | ///
7 | public string DatabaseName { get; private set; } = Constants.DatabaseFileName;
8 |
9 | ///
10 | public string DatabaseDirectory { get; internal set; } = string.Empty;
11 |
12 | ///
13 | public TimeSpan UpdateInterval { get; set; } = TimeSpan.FromDays(1);
14 | }
15 |
--------------------------------------------------------------------------------
/src/Mocale.Cache.SQLite/Properties/GlobalSuppression.cs:
--------------------------------------------------------------------------------
1 | // This file is used by Code Analysis to maintain SuppressMessage attributes that are applied to
2 | // this project. Project-level suppressions either have no target or are given a specific target and
3 | // scoped to a namespace, type, member, etc.
4 |
5 | using System.Diagnostics.CodeAnalysis;
6 | [assembly: SuppressMessage("Performance", "CA1848:Use the LoggerMessage delegates", Justification = "This message is annoying, why provide methods we can't use?")]
7 |
--------------------------------------------------------------------------------
/tests/Mocale.UnitTests/Resources/en-GB.json:
--------------------------------------------------------------------------------
1 | {
2 | "CurrentLocaleName": "English",
3 | "LocalizationCurrentProviderIs": "The current localization provider is:",
4 | "LocalizationProviderName": "Json",
5 | "MocaleDescription": "Localization framework for .NET Maui",
6 | "MocaleTitle": "Mocale",
7 | "ExternalPrefixExplanation": "Strings prefixed with GR_ indicate they have been pulled from the external provider (GitHub.Raw), when the local cache expires if these values change, so will the text displayed!"
8 | }
9 |
--------------------------------------------------------------------------------
/src/Mocale.Providers.Azure.Blob/Properties/GlobalSuppression.cs:
--------------------------------------------------------------------------------
1 | // This file is used by Code Analysis to maintain SuppressMessage attributes that are applied to
2 | // this project. Project-level suppressions either have no target or are given a specific target and
3 | // scoped to a namespace, type, member, etc.
4 |
5 | using System.Diagnostics.CodeAnalysis;
6 | [assembly: SuppressMessage("Performance", "CA1848:Use the LoggerMessage delegates", Justification = "This message is annoying, why provide methods we can't use?")]
7 |
--------------------------------------------------------------------------------
/src/Mocale.Providers.GitHub.Raw/Properties/GlobalSuppression.cs:
--------------------------------------------------------------------------------
1 | // This file is used by Code Analysis to maintain SuppressMessage attributes that are applied to
2 | // this project. Project-level suppressions either have no target or are given a specific target and
3 | // scoped to a namespace, type, member, etc.
4 |
5 | using System.Diagnostics.CodeAnalysis;
6 | [assembly: SuppressMessage("Performance", "CA1848:Use the LoggerMessage delegates", Justification = "This message is annoying, why provide methods we can't use?")]
7 |
--------------------------------------------------------------------------------
/src/Mocale/Abstractions/IExternalLocalizationResult.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Abstractions;
2 |
3 | ///
4 | /// External Localization Result
5 | ///
6 | public interface IExternalLocalizationResult
7 | {
8 | ///
9 | /// Whether the attempt succeeded
10 | ///
11 | bool Success { get; }
12 |
13 | ///
14 | /// Localizations from the external provider
15 | ///
16 | Dictionary? Localizations { get; }
17 | }
18 |
--------------------------------------------------------------------------------
/src/Mocale.Providers.Azure.Blob/Models/BlobResourceInfo.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Providers.Azure.Blob.Models;
2 |
3 | ///
4 | /// Blob Resource Information
5 | ///
6 | public class BlobResourceInfo
7 | {
8 | ///
9 | /// Whether the theorized blob resource actually exists
10 | ///
11 | public bool Exists { get; init; }
12 |
13 | ///
14 | /// The name of the theorized blob resource
15 | ///
16 | public string? ResourceName { get; init; }
17 | }
18 |
--------------------------------------------------------------------------------
/src/Mocale/Abstractions/IResourceFileDetails.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Abstractions;
2 |
3 | ///
4 | /// Resource File Details
5 | ///
6 | public interface IResourceFileDetails
7 | {
8 | ///
9 | /// The type of file being stored externally
10 | ///
11 | LocaleResourceType ResourceType { get; }
12 |
13 | ///
14 | /// The version prefix of the files, this will be prepended after the url & before the file name
15 | ///
16 | string? VersionPrefix { get; }
17 | }
18 |
--------------------------------------------------------------------------------
/tests/Mocale.UnitTests/Collections/CollectionDefinitions.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.UnitTests.Collections;
2 |
3 | [CollectionDefinition(CollectionNames.MocaleLocatorTests, DisableParallelization = true)]
4 | public class MocaleLocatorTestsCollectionDefinition;
5 |
6 | [CollectionDefinition(CollectionNames.ThreadCultureTests, DisableParallelization = true)]
7 | public class ThreadCultureTestsCollectionDefinition;
8 |
9 | [CollectionDefinition(CollectionNames.TestingTests, DisableParallelization = true)]
10 | public class TestingTestsCollectionDefinition;
11 |
--------------------------------------------------------------------------------
/src/Mocale.Providers.Azure.Blob/Abstractions/IBlobResourceLocator.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Providers.Azure.Blob.Abstractions;
2 |
3 | ///
4 | /// Blob Resource Locator
5 | ///
6 | public interface IBlobResourceLocator
7 | {
8 | ///
9 | /// Try to locate blob resource for the given culture
10 | ///
11 | /// The culture to try locate blob resource for
12 | /// Result of location
13 | Task TryLocateResource(CultureInfo cultureInfo);
14 | }
15 |
--------------------------------------------------------------------------------
/src/Mocale/Abstractions/ITranslationUpdater.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Abstractions;
2 |
3 | ///
4 | /// Translation Updater
5 | ///
6 | internal interface ITranslationUpdater
7 | {
8 | ///
9 | /// Update Translations From Source
10 | ///
11 | ///
12 | ///
13 | /// Whether this should notify observers
14 | void UpdateTranslations(Localization localization, TranslationSource source, bool notify = true);
15 | }
16 |
--------------------------------------------------------------------------------
/src/Mocale/Providers/InactiveExternalLocalizationProvider.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 | namespace Mocale.Providers;
3 |
4 | internal sealed class InactiveExternalLocalizationProvider : IExternalLocalizationProvider
5 | {
6 | public Task GetValuesForCultureAsync(CultureInfo cultureInfo)
7 | {
8 | IExternalLocalizationResult blankResult = new ExternalLocalizationResult()
9 | {
10 | Success = false,
11 | Localizations = null,
12 | };
13 |
14 | return Task.FromResult(blankResult);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Mocale.Providers.GitHub.Raw/Helpers/RawUrlBuilder.cs:
--------------------------------------------------------------------------------
1 | using Mocale.Extensions;
2 | namespace Mocale.Providers.GitHub.Raw.Helpers;
3 |
4 | internal static class RawUrlBuilder
5 | {
6 | public static Uri BuildResourceUrl(string username, string repository, string branch, string filePath, string fileName)
7 | {
8 | // https://raw.githubusercontent.com/Axemasta/Mocale/github-provider/samples/Locales/fr-FR.json
9 | return new Uri("https://raw.githubusercontent.com/")
10 | .Append(username, repository, branch, filePath, fileName);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/tests/Mocale.UnitTests/MocaleLocatorTests.cs:
--------------------------------------------------------------------------------
1 | using Mocale.Abstractions;
2 | using Mocale.Testing;
3 |
4 | namespace Mocale.UnitTests;
5 |
6 | public class MocaleLocatorTests
7 | {
8 | [Fact]
9 | public void SetInstance_Should_SetInstance()
10 | {
11 | // Arrange
12 | var translatorManager = new Mock();
13 |
14 | // Act
15 | MocaleLocatorHelper.SetTranslatorManager(translatorManager.Object);
16 |
17 | // Assert
18 | Assert.Equal(translatorManager.Object, MocaleLocator.TranslatorManager);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/Mocale/Abstractions/ICurrentCultureManager.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 |
3 | namespace Mocale.Abstractions;
4 |
5 | ///
6 | /// Current Culture Manager
7 | ///
8 | public interface ICurrentCultureManager
9 | {
10 | ///
11 | /// Get Active Culture
12 | ///
13 | ///
14 | CultureInfo GetActiveCulture();
15 |
16 | ///
17 | /// Set Active Culture
18 | ///
19 | ///
20 | void SetActiveCulture(CultureInfo cultureInfo);
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/src/Mocale/Models/TranslationLoadResult.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Models;
2 |
3 | ///
4 | /// Translation Load Result
5 | ///
6 | public class TranslationLoadResult
7 | {
8 | ///
9 | /// Whether translations were loaded
10 | ///
11 | public bool Loaded { get; set; }
12 |
13 | ///
14 | /// Source of the translations
15 | ///
16 | public TranslationSource Source { get; set; }
17 |
18 | ///
19 | ///
20 | ///
21 | public required Localization Localization { get; set; }
22 | }
23 |
--------------------------------------------------------------------------------
/tests/Mocale.UnitTests/Snapshots/TranslationKeySourceGeneratorSnapshotTests.GeneratesTranslationKeys_WhenNoAdditionalFiles_ShouldGenerateNoKeys.verified.txt:
--------------------------------------------------------------------------------
1 | {
2 | Diagnostics: [
3 | {
4 | Message: No localizations files were found to process,
5 | Severity: Warning,
6 | WarningLevel: 1,
7 | Descriptor: {
8 | Id: MOCW001,
9 | Title: No localizations files were found to process,
10 | MessageFormat: No localizations files were found to process,
11 | Category: Mocale.SourceGenerators,
12 | DefaultSeverity: Warning,
13 | IsEnabledByDefault: true
14 | }
15 | }
16 | ]
17 | }
18 |
--------------------------------------------------------------------------------
/tests/Mocale.UnitTests/TestUtils/TranslationKeySourceGeneratorSnapshotTests.GeneratesTranslationKeys_WhenNoAdditionalFiles_ShouldGenerateNoKeys.verified.txt:
--------------------------------------------------------------------------------
1 | {
2 | Diagnostics: [
3 | {
4 | Message: No localizations files were found to process,
5 | Severity: Warning,
6 | WarningLevel: 1,
7 | Descriptor: {
8 | Id: MOCW001,
9 | Title: No localizations files were found to process,
10 | MessageFormat: No localizations files were found to process,
11 | Category: Mocale.SourceGenerators,
12 | DefaultSeverity: Warning,
13 | IsEnabledByDefault: true
14 | }
15 | }
16 | ]
17 | }
18 |
--------------------------------------------------------------------------------
/src/Mocale.Cache.SQLite/Providers/DatabasePathProvider.cs:
--------------------------------------------------------------------------------
1 | using Mocale.Abstractions;
2 | namespace Mocale.Cache.SQLite.Providers;
3 |
4 | internal class DatabasePathProvider(IConfigurationManager configurationManager)
5 | : IDatabasePathProvider
6 | {
7 | private readonly IConfigurationManager configurationManager = Guard.Against.Null(configurationManager, nameof(configurationManager));
8 |
9 | public string GetDatabasePath()
10 | {
11 | var config = configurationManager.Configuration;
12 |
13 | return Path.Combine(config.DatabaseDirectory, config.DatabaseName);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/Mocale/Abstractions/IEmbeddedResourcesConfig.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | namespace Mocale.Abstractions;
3 |
4 | internal interface IEmbeddedResourcesConfig
5 | {
6 | ///
7 | /// Path to the resources directory
8 | ///
9 | string ResourcesPath { get; }
10 |
11 | ///
12 | /// Assembly that contains the resources
13 | ///
14 | Assembly? ResourcesAssembly { get; }
15 |
16 | ///
17 | /// Whether the resources live inside the Maui Resources folder or relative to the assembly
18 | ///
19 | bool UseResourceFolder { get; }
20 | }
21 |
--------------------------------------------------------------------------------
/samples/Mocale.Samples/App.xaml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/Mocale.Providers.Azure.Blob/Models/BlobStorageConfig.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Providers.Azure.Blob.Models;
2 |
3 | ///
4 | public class BlobStorageConfig : IBlobStorageConfig
5 | {
6 | ///
7 | public Uri BlobContainerUri { get; set; } = new Uri("app://mocale"); // Default value so we don't have to mark as nullable
8 |
9 | ///
10 | public bool RequiresAuthentication { get; set; }
11 |
12 | ///
13 | public bool CheckForFile { get; set; } = true;
14 |
15 | ///
16 | public IResourceFileDetails ResourceFileDetails { get; set; } = new JsonResourceFileDetails();
17 | }
18 |
--------------------------------------------------------------------------------
/src/Mocale/Abstractions/IExternalLocalizationProvider.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 | namespace Mocale.Abstractions;
3 |
4 | ///
5 | /// External Localization Provider - Provides localizations from an external source
6 | ///
7 | public interface IExternalLocalizationProvider
8 | {
9 | ///
10 | /// Gets Values For Culture using the external source
11 | ///
12 | /// The culture to attempt to load
13 | /// External localization result for the given culture
14 | Task GetValuesForCultureAsync(CultureInfo cultureInfo);
15 | }
16 |
--------------------------------------------------------------------------------
/src/Mocale.Cache.SQLite/Abstractions/ISqliteConfig.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Cache.SQLite.Abstractions;
2 |
3 | ///
4 | /// Configuration For SQLite Cache Library
5 | ///
6 | public interface ISqliteConfig
7 | {
8 | ///
9 | /// The name of the cache database
10 | ///
11 | string DatabaseName { get; }
12 |
13 | ///
14 | /// The database directory: FileSystem.AppDataDirectory
15 | ///
16 | string DatabaseDirectory { get; }
17 |
18 | ///
19 | /// The interval in which the cache should be updated
20 | ///
21 | TimeSpan UpdateInterval { get; }
22 | }
23 |
--------------------------------------------------------------------------------
/tests/Mocale.UnitTests/Resources/Misc/TestFile.json:
--------------------------------------------------------------------------------
1 | {
2 | "glossary": {
3 | "title": "example glossary",
4 | "GlossDiv": {
5 | "title": "S",
6 | "GlossList": {
7 | "GlossEntry": {
8 | "ID": "SGML",
9 | "SortAs": "SGML",
10 | "GlossTerm": "Standard Generalized Markup Language",
11 | "Acronym": "SGML",
12 | "Abbrev": "ISO 8879:1986",
13 | "GlossDef": {
14 | "para": "A meta-markup language, used to create markup languages such as DocBook.",
15 | "GlossSeeAlso": ["GML", "XML"]
16 | },
17 | "GlossSee": "markup"
18 | }
19 | }
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/Mocale/Models/Localization.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 | namespace Mocale.Models;
3 |
4 | ///
5 | /// Localization
6 | ///
7 | public class Localization(CultureInfo cultureInfo)
8 | {
9 | ///
10 | /// Corresponding culture
11 | ///
12 | public CultureInfo CultureInfo { get; } = cultureInfo;
13 |
14 | ///
15 | /// Translations
16 | ///
17 | public Dictionary Translations { get; set; } = [];
18 |
19 | ///
20 | /// Blank localization
21 | ///
22 | public static Localization Invariant => new(CultureInfo.InvariantCulture);
23 | }
24 |
--------------------------------------------------------------------------------
/tests/Mocale.UnitTests/Resources/Invalid/en-GB.json:
--------------------------------------------------------------------------------
1 |
2 |
3 | English
4 | The current localization provider is:
5 | Json
6 | Localization framework for .NET Maui
7 | Mocale
8 | Strings prefixed with GR_ indicate they have been pulled from the external provider (GitHub.Raw), when the local cache expires if these values change, so will the text displayed!
9 |
10 |
--------------------------------------------------------------------------------
/samples/Mocale.Samples/Properties/GlobalSuppression.cs:
--------------------------------------------------------------------------------
1 | #pragma warning disable IDE0076
2 | /*
3 | * Platform Suppressions
4 | *
5 | * The dotnet analyzers don't work properly when suppressions apply only to files not currently beign targetted.
6 | * ie a suppression rule for iOS / macOS won't apply when targetting windows / android and the compiler with
7 | * erroniously assume the suppression is invalid.
8 | */
9 | using System.Diagnostics.CodeAnalysis;
10 |
11 | [assembly: SuppressMessage("Naming", "CA1711:Identifiers should not have incorrect suffix", Justification = "iOS / macOS Platform Name", Scope = "type", Target = "~T:Mocale.Samples.AppDelegate")]
12 | #pragma warning restore IDE0076
13 |
--------------------------------------------------------------------------------
/src/Mocale.Providers.GitHub.Raw/Models/GithubRawConfig.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Providers.GitHub.Raw.Models;
2 |
3 | ///
4 | public class GithubRawConfig : IGithubRawConfig
5 | {
6 | ///
7 | public string Username { get; set; } = string.Empty;
8 |
9 | ///
10 | public string Repository { get; set; } = string.Empty;
11 |
12 | ///
13 | public string Branch { get; set; } = "main";
14 |
15 | ///
16 | public string LocaleDirectory { get; set; } = string.Empty;
17 |
18 | ///
19 | public IResourceFileDetails ResourceFileDetails { get; set; } = new JsonResourceFileDetails();
20 | }
21 |
--------------------------------------------------------------------------------
/src/Mocale/Abstractions/IInternalLocalizationProvider.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 | namespace Mocale.Abstractions;
3 |
4 | ///
5 | /// IInternalLocalizationProvider - Responsible for providing localizations from internally within
6 | /// the application.
7 | ///
8 | public interface IInternalLocalizationProvider
9 |
10 | {
11 | ///
12 | /// Gets the localization values for the given culture
13 | ///
14 | /// The culture to get localizations for
15 | /// The localizations as a key value pair
16 | Dictionary? GetValuesForCulture(CultureInfo cultureInfo);
17 | }
18 |
--------------------------------------------------------------------------------
/src/Mocale/Managers/ConfigurationManager.cs:
--------------------------------------------------------------------------------
1 | using Ardalis.GuardClauses;
2 |
3 | namespace Mocale.Managers;
4 |
5 | ///
6 | /// Simple Singleton Style Class For Storing Configuration Objects
7 | ///
8 | ///
9 | public class ConfigurationManager(TConfig config)
10 | : IConfigurationManager, IConfigurationUpdateManager
11 | {
12 | ///
13 | public TConfig Configuration { get; } = Guard.Against.Null(config, nameof(config));
14 |
15 | ///
16 | public void UpdateConfiguration(Action configuration)
17 | {
18 | configuration(Configuration);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/Mocale/MocaleInitializeService.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale;
2 |
3 | internal class MocaleInitializeService : IMauiInitializeService
4 | {
5 | public void Initialize(IServiceProvider services)
6 | {
7 | var localizationManager = services.GetRequiredService();
8 | var translatorManager = services.GetRequiredService();
9 | var configManager = services.GetRequiredService>();
10 |
11 | MocaleLocator.MocaleConfiguration = configManager.Configuration;
12 | MocaleLocator.TranslatorManager = translatorManager;
13 |
14 | Task.Run(localizationManager.Initialize);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/samples/Mocale.Samples/Resources/Raw/AboutAssets.txt:
--------------------------------------------------------------------------------
1 | Any raw assets you want to be deployed with your application can be placed in
2 | this directory (and child directories). Deployment of the asset to your application
3 | is automatically handled by the following `MauiAsset` Build Action within your `.csproj`.
4 |
5 |
6 |
7 | These files will be deployed with you package and will be accessible using Essentials:
8 |
9 | async Task LoadMauiAsset()
10 | {
11 | using var stream = await FileSystem.OpenAppPackageFileAsync("AboutAssets.txt");
12 | using var reader = new StreamReader(stream);
13 |
14 | var contents = reader.ReadToEnd();
15 | }
16 |
--------------------------------------------------------------------------------
/src/Mocale/Enums/TranslationSource.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Enums;
2 |
3 | ///
4 | /// Translation Source
5 | ///
6 | public enum TranslationSource
7 | {
8 | ///
9 | /// Translations came from internal provider (locally).
10 | ///
11 | Internal = 0,
12 |
13 | ///
14 | /// Translations came from external provider.
15 | ///
16 | External = 1,
17 |
18 | ///
19 | /// Translations came from cache, and the cache is up to date.
20 | ///
21 | WarmCache = 2,
22 |
23 | ///
24 | /// Translations came from cache, and the cache is expired (can be updated).
25 | ///
26 | ColdCache = 4,
27 | }
28 |
--------------------------------------------------------------------------------
/src/Mocale/Models/ResxResourceFileDetails.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 |
3 | namespace Mocale.Models;
4 |
5 | ///
6 | public class ResxResourceFileDetails : IResourceFileDetails
7 | {
8 | ///
9 | public LocaleResourceType ResourceType { get; } = LocaleResourceType.Resx;
10 |
11 | ///
12 | public string? VersionPrefix { get; set; }
13 |
14 | ///
15 | /// The name of the resource file
16 | ///
17 | public required string ResourcePrefix { get; set; }
18 |
19 | ///
20 | /// The primary resources culture (if this exists). This will not have the culture suffix in its file path.
21 | ///
22 | public CultureInfo? PrimaryCulture { get; set; }
23 | }
24 |
--------------------------------------------------------------------------------
/src/Mocale/Parsers/JsonLocalizationParser.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json;
2 | using Ardalis.GuardClauses;
3 |
4 | namespace Mocale.Parsers;
5 |
6 | internal class JsonLocalizationParser(ILogger logger) : ILocalizationParser
7 | {
8 | private readonly ILogger logger = Guard.Against.Null(logger, nameof(logger));
9 |
10 | public Dictionary? ParseLocalizationStream(Stream resourceStream)
11 | {
12 | try
13 | {
14 | return JsonSerializer.Deserialize>(resourceStream);
15 | }
16 | catch (Exception ex)
17 | {
18 | logger.LogError(ex, "An exception occurred parsing localization stream");
19 | return null;
20 | }
21 | }
22 | }
23 |
24 |
--------------------------------------------------------------------------------
/src/Mocale/Abstractions/IKeyConverter.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 |
3 | namespace Mocale.Abstractions;
4 |
5 | ///
6 | /// Translation Key Converter
7 | ///
8 | public interface IKeyConverter
9 | {
10 | ///
11 | /// Convert the current object into a translation key
12 | ///
13 | /// The value to convert into a translation key
14 | /// The target type for the control the localization is being applied
15 | /// The parameter to use for the conversion
16 | /// The culture for the conversion
17 | ///
18 | string? Convert(object? value, Type targetType, object? parameter, CultureInfo culture);
19 | }
20 |
--------------------------------------------------------------------------------
/samples/Mocale.Samples/Platforms/Windows/App.xaml.cs:
--------------------------------------------------------------------------------
1 | // To learn more about WinUI, the WinUI project structure,
2 | // and more about our project templates, see: http://aka.ms/winui-project-info.
3 |
4 | namespace Mocale.Samples.WinUI;
5 |
6 | ///
7 | /// Provides application-specific behavior to supplement the default Application class.
8 | ///
9 | public partial class App : MauiWinUIApplication
10 | {
11 | ///
12 | /// Initializes the singleton application object. This is the first line of authored code
13 | /// executed, and as such is the logical equivalent of main() or WinMain().
14 | ///
15 | public App()
16 | {
17 | this.InitializeComponent();
18 | }
19 |
20 | protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
21 | }
22 |
--------------------------------------------------------------------------------
/samples/Mocale.Samples/Platforms/Windows/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 | true/PM
12 | PerMonitorV2, PerMonitor
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/tests/Mocale.UnitTests/Resources/Resx/TestResources.fr-fr.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 | text/microsoft-resx
4 |
5 |
6 | 1.3
7 |
8 |
9 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
10 |
11 |
12 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
13 |
14 |
15 | Clé deux
16 |
17 |
18 | Clé un
19 |
20 |
--------------------------------------------------------------------------------
/src/Mocale.Testing/Mocale.Testing.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $(StandardTargetFramework)
5 |
6 | Mocale.Testing
7 | Mocale.Testing
8 | Mocale.Testing
9 | Testing compatibility package for mocale
10 | maui,mocale,localization,localisation,translation,testing,mocale.testing
11 | Mocale.Testing
12 | Testing compatibility package for Mocale to enable seemless unit testing of Maui components that use mocale.
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/Mocale/Abstractions/IConfigurationManager.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Abstractions;
2 |
3 | ///
4 | /// Configuration Manager
5 | ///
6 | /// The config for this manager
7 | public interface IConfigurationManager
8 | {
9 | ///
10 | /// The configuration for the given area
11 | ///
12 | TConfig Configuration { get; }
13 | }
14 |
15 | ///
16 | /// Configuration Update Manager
17 | ///
18 | ///
19 | public interface IConfigurationUpdateManager
20 | {
21 | ///
22 | /// Update Configuration
23 | ///
24 | ///
25 | void UpdateConfiguration(Action configuration);
26 | }
27 |
--------------------------------------------------------------------------------
/samples/Mocale.Samples/Platforms/Tizen/tizen-manifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | maui-appicon-placeholder
7 |
8 |
9 |
10 |
11 | http://tizen.org/privilege/internet
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/Mocale/Abstractions/ILocalizationManager.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 | namespace Mocale.Abstractions;
3 |
4 | ///
5 | /// Localization Manager
6 | ///
7 | public interface ILocalizationManager
8 | {
9 | ///
10 | /// The current culture
11 | ///
12 | CultureInfo CurrentCulture { get; }
13 |
14 | ///
15 | /// Mocale Bootstrapper, this is called internall by mocale during maui app startup
16 | ///
17 | /// Success
18 | Task Initialize();
19 |
20 | ///
21 | /// Set culture
22 | ///
23 | /// The culture to attempt to display
24 | /// Success
25 | Task SetCultureAsync(CultureInfo culture);
26 | }
27 |
--------------------------------------------------------------------------------
/samples/Mocale.Samples/Enums/Cities.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 |
3 | namespace Mocale.Samples.Enums;
4 |
5 | public enum Cities
6 | {
7 | [Description("CityDescription_London")]
8 | [MocaleTranslationKey("CityDescription_London")]
9 | London,
10 |
11 | [Description("CityDescription_Nottingham")]
12 | [MocaleTranslationKey("CityDescription_Nottingham")]
13 | Nottingham,
14 |
15 | [Description("CityDescription_Newcastle")]
16 | [MocaleTranslationKey("CityDescription_Newcastle")]
17 | Newcastle,
18 |
19 | [Description("CityDescription_Manchester")]
20 | [MocaleTranslationKey("CityDescription_Manchester")]
21 | Manchester,
22 | }
23 |
24 | [AttributeUsage(AttributeTargets.Field)]
25 | public class MocaleTranslationKeyAttribute(string key) : Attribute
26 | {
27 | public string Key { get; set; } = key;
28 | }
29 |
--------------------------------------------------------------------------------
/src/Mocale.Providers.GitHub.Raw/Abstractions/IGithubRawConfig.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Providers.GitHub.Raw.Abstractions;
2 |
3 | ///
4 | /// External provider configuration for github raw source
5 | ///
6 | public interface IGithubRawConfig : IExternalProviderConfiguration
7 | {
8 | ///
9 | /// The github username
10 | ///
11 | string Username { get; }
12 |
13 | ///
14 | /// The repository to target
15 | ///
16 | string Repository { get; }
17 |
18 | ///
19 | /// The branch the localizations exist on
20 | ///
21 | string Branch { get; }
22 |
23 | ///
24 | /// The directory in the repository that contains the locale files
25 | ///
26 | string LocaleDirectory { get; }
27 | }
28 |
--------------------------------------------------------------------------------
/samples/Mocale.GeneratorSample/Mocale.GeneratorSample.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | $(StandardTargetFramework)
6 | enable
7 | enable
8 | true
9 | $(NoWarn);IDE0005
10 | Locales\*.json
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/Mocale/Extensions/UriExtension.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Extensions;
2 |
3 | internal static class UriExtension
4 | {
5 | public static Uri Append(this Uri uri, params string[] paths)
6 | {
7 | // https://stackoverflow.com/a/7993235/8828057
8 | return new Uri(paths.Aggregate(uri.AbsoluteUri, (current, path) => $"{current.TrimEnd('/')}/{path.TrimStart('/')}"));
9 | }
10 |
11 | public static bool TryAppend(this Uri uri, out Uri result, params string[] paths)
12 | {
13 | result = default!;
14 |
15 | var appendedUri = uri.Append(paths);
16 |
17 | var wellFormed = Uri.IsWellFormedUriString(appendedUri.ToString(), UriKind.Absolute);
18 |
19 | if (wellFormed)
20 | {
21 | result = appendedUri;
22 | }
23 |
24 | return wellFormed;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/Mocale.Cache.SQLite/Repositories/RepositoryBase.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.Logging;
2 | namespace Mocale.Cache.SQLite.Repositories;
3 |
4 | internal abstract class RepositoryBase
5 | {
6 | #pragma warning disable IDE1006
7 | // ReSharper disable once InconsistentNaming
8 | protected ILogger logger { get; }
9 | #pragma warning restore IDE1006
10 |
11 | protected SQLiteConnection Connection { get; }
12 |
13 | protected RepositoryBase(
14 | IDatabaseConnectionProvider databaseConnectionProvider,
15 | ILogger logger)
16 | {
17 | databaseConnectionProvider = Guard.Against.Null(databaseConnectionProvider, nameof(databaseConnectionProvider));
18 | this.logger = Guard.Against.Null(logger, nameof(logger));
19 |
20 | Connection = databaseConnectionProvider.GetDatabaseConnection();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/Mocale/Abstractions/ITranslationResolver.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 | namespace Mocale.Abstractions;
3 |
4 | ///
5 | /// Translation Resolver
6 | ///
7 | public interface ITranslationResolver
8 | {
9 | ///
10 | /// Load Translations For Given Culture
11 | ///
12 | /// The culture to load
13 | /// The load result
14 | Task LoadTranslations(CultureInfo cultureInfo);
15 |
16 | ///
17 | /// Load Local Translations For Given Culture
18 | /// Local is defined as either from cache of on the device
19 | ///
20 | /// The culture to load
21 | /// The load result
22 | TranslationLoadResult LoadLocalTranslations(CultureInfo cultureInfo);
23 | }
24 |
--------------------------------------------------------------------------------
/tests/Mocale.UnitTests/Snapshots/TranslationKeySourceGeneratorSnapshotTests.GeneratesTranslationKeys_WhenSingleFile_ShouldGenerateCorrectly#MocaleTranslationKeys.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: MocaleTranslationKeys.g.cs
2 | namespace Mocale.Translations
3 | {
4 | public static class TranslationKeys
5 | {
6 | ///
7 | /// Looks up a localized string using key KeyOne.
8 | ///
9 | public const string KeyOne = "KeyOne";
10 |
11 | ///
12 | /// Looks up a localized string using key Key_Two.
13 | ///
14 | public const string KeyTwo = "Key_Two";
15 |
16 | ///
17 | /// Looks up a localized string using key Key@!_/Three.
18 | ///
19 | public const string KeyThree = "Key@!_/Three";
20 |
21 | ///
22 | /// Looks up a localized string using key Key.Four.
23 | ///
24 | public const string KeyFour = "Key.Four";
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/tests/Mocale.UnitTests/TestUtils/TranslationKeySourceGeneratorSnapshotTests.GeneratesTranslationKeys_WhenSingleFile_ShouldGenerateCorrectly#MocaleTranslationKeys.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: MocaleTranslationKeys.g.cs
2 | namespace Mocale.Translations
3 | {
4 | public static class TranslationKeys
5 | {
6 | ///
7 | /// Looks up a localized string using key KeyOne.
8 | ///
9 | public const string KeyOne = "KeyOne";
10 |
11 | ///
12 | /// Looks up a localized string using key Key_Two.
13 | ///
14 | public const string KeyTwo = "Key_Two";
15 |
16 | ///
17 | /// Looks up a localized string using key Key@!_/Three.
18 | ///
19 | public const string KeyThree = "Key@!_/Three";
20 |
21 | ///
22 | /// Looks up a localized string using key Key.Four.
23 | ///
24 | public const string KeyFour = "Key.Four";
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/samples/Mocale.Samples/ViewModels/ConverterViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Samples.ViewModels;
2 |
3 | public partial class ConverterViewModel : BaseViewModel
4 | {
5 | [ObservableProperty]
6 | public partial OrderStatus CurrentStatus { get; set; }
7 |
8 | public ObservableRangeCollection OrderStatuses { get; } =
9 | [
10 | new OrderStatus("Pending", 0),
11 | new OrderStatus("Shipped", 1),
12 | new OrderStatus("Delivered", 2),
13 | new OrderStatus("Cancelled", 3),
14 | ];
15 |
16 | public ConverterViewModel()
17 | {
18 | CurrentStatus = OrderStatuses[0];
19 | }
20 | }
21 |
22 | public partial class OrderStatus(string name, int stage) : ObservableObject
23 | {
24 | [ObservableProperty]
25 | public partial string Name { get; set; } = name;
26 |
27 | [ObservableProperty]
28 | public partial int Stage { get; set; } = stage;
29 | }
30 |
--------------------------------------------------------------------------------
/src/Mocale/Abstractions/ILocalisationCacheManager.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 | namespace Mocale.Abstractions;
3 |
4 | ///
5 | /// Localisation Cache Manager
6 | ///
7 | public interface ILocalisationCacheManager
8 | {
9 | ///
10 | /// Get Cached Localizations For Culture
11 | ///
12 | /// Culture to get cached values for
13 | /// Cached localizations if they exist
14 | Dictionary? GetCachedLocalizations(CultureInfo cultureInfo);
15 |
16 | ///
17 | /// Set Cached Localizations For Culture
18 | ///
19 | ///
20 | ///
21 | ///
22 | bool SaveCachedLocalizations(CultureInfo cultureInfo, Dictionary localizations);
23 | }
24 |
--------------------------------------------------------------------------------
/src/Mocale/Extensions/TaskExtensions.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.Extensions;
2 |
3 | internal static class TaskExtensions
4 | {
5 | // https://www.meziantou.net/fire-and-forget-a-task-in-dotnet.htm
6 | public static void Forget(this Task task)
7 | {
8 | // Only care about tasks that may fault or are faulted,
9 | // so fast-path for SuccessfullyCompleted and Canceled tasks
10 | if (!task.IsCompleted || task.IsFaulted)
11 | {
12 | _ = ForgetAwaited(task);
13 | }
14 |
15 | static async Task ForgetAwaited(Task task)
16 | {
17 | try
18 | {
19 | // No need to resume on the original SynchronizationContext
20 | await task.ConfigureAwait(false);
21 | }
22 | catch
23 | {
24 | // Nothing to do here
25 | }
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/tests/Mocale.UnitTests/Fixtures/FixtureBase.cs:
--------------------------------------------------------------------------------
1 | namespace Mocale.UnitTests.Fixtures;
2 |
3 | public abstract class FixtureBase : MocaleLocatorFixture
4 | {
5 | private Lazy SutLazy { get; init; }
6 |
7 | protected TSut Sut => SutLazy.Value;
8 |
9 | public FixtureBase()
10 | {
11 | SutLazy = new Lazy(CreateSystemUnderTest, LazyThreadSafetyMode.ExecutionAndPublication);
12 | }
13 |
14 | public abstract TSut CreateSystemUnderTest();
15 | }
16 |
17 | public abstract class FixtureBase : MocaleLocatorFixture
18 | {
19 | private Lazy