// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. #pragma once #include "CalcManager/UnitConverter.h" #include "Common/NetworkManager.h" #include "ICurrencyHttpClient.h" namespace CalculatorApp { namespace ViewModel { public enum class CurrencyLoadStatus { NotLoaded = 0, FailedToLoad = 1, LoadedFromCache = 2, LoadedFromWeb = 3 }; namespace UnitConverterResourceKeys { extern Platform::StringReference CurrencyUnitFromKey; extern Platform::StringReference CurrencyUnitToKey; } namespace CurrencyDataLoaderConstants { extern Platform::StringReference CacheTimestampKey; extern Platform::StringReference CacheLangcodeKey; extern Platform::StringReference CacheDelimiter; extern Platform::StringReference StaticDataFilename; extern Platform::StringReference AllRatiosDataFilename; extern long long DayDuration; } namespace UCM = UnitConversionManager; typedef std::unordered_map CurrencyRatioMap; typedef std::pair SelectedUnits; struct CurrencyUnitMetadata { CurrencyUnitMetadata(const std::wstring& s) : symbol(s) { } const std::wstring symbol; }; class CurrencyDataLoader : public UCM::IConverterDataLoader, public UCM::ICurrencyConverterDataLoader { public: CurrencyDataLoader(_In_ std::unique_ptr client, const wchar_t* overrideLanguage = nullptr); ~CurrencyDataLoader(); bool LoadFinished(); bool LoadedFromCache(); bool LoadedFromWeb(); // IConverterDataLoader void LoadData() override; std::vector LoadOrderedCategories() override; std::vector LoadOrderedUnits(const UCM::Category& category) override; std::unordered_map LoadOrderedRatios(const UCM::Unit& unit) override; bool SupportsCategory(const UnitConversionManager::Category& target) override; // IConverterDataLoader // ICurrencyConverterDataLoader void SetViewModelCallback(const std::shared_ptr& callback) override; std::pair GetCurrencySymbols(const UCM::Unit& unit1, const UCM::Unit& unit2) override; std::pair GetCurrencyRatioEquality(_In_ const UnitConversionManager::Unit& unit1, _In_ const UnitConversionManager::Unit& unit2) override; std::wstring GetCurrencyTimestamp() override; static double RoundCurrencyRatio(double ratio); std::future TryLoadDataFromCacheAsync() override; std::future TryLoadDataFromWebAsync() override; std::future TryLoadDataFromWebOverrideAsync() override; // ICurrencyConverterDataLoader void OnNetworkBehaviorChanged(CalculatorApp::NetworkAccessBehavior newBehavior); private: void ResetLoadStatus(); void NotifyDataLoadFinished(bool didLoad); std::future TryFinishLoadFromCacheAsync(); bool TryParseWebResponses( _In_ Platform::String ^ staticDataJson, _In_ Platform::String ^ allRatiosJson, _Inout_ std::vector& staticData, _Inout_ CurrencyRatioMap& allRatiosData); bool TryParseStaticData(_In_ Platform::String ^ rawJson, _Inout_ std::vector& staticData); bool TryParseAllRatiosData(_In_ Platform::String ^ rawJson, _Inout_ CurrencyRatioMap& allRatiosData); concurrency::task FinalizeUnits(_In_ const std::vector& staticData, _In_ const CurrencyRatioMap& ratioMap); void GuaranteeSelectedUnits(); void SaveLangCodeAndTimestamp(); void UpdateDisplayedTimestamp(); void RegisterForNetworkBehaviorChanges(); void UnregisterForNetworkBehaviorChanges(); concurrency::task GetDefaultFromToCurrency(); bool TryGetLastUsedCurrenciesFromLocalSettings(_Out_ std::wstring* const fromCurrency, _Out_ std::wstring* const toCurrency); void SaveSelectedUnitsToLocalSettings(_In_ const SelectedUnits& selectedUnits); private: Platform::String ^ m_responseLanguage; std::unique_ptr m_client; bool m_isRtlLanguage; std::mutex m_currencyUnitsMutex; std::vector m_currencyUnits; UCM::UnitToUnitToConversionDataMap m_currencyRatioMap; std::unordered_map m_currencyMetadata; std::shared_ptr m_vmCallback; Windows::Globalization::NumberFormatting::DecimalFormatter ^ m_ratioFormatter; std::wstring m_ratioFormat; Windows::Foundation::DateTime m_cacheTimestamp; std::wstring m_timestampFormat; CurrencyLoadStatus m_loadStatus; CalculatorApp::NetworkManager ^ m_networkManager; CalculatorApp::NetworkAccessBehavior m_networkAccessBehavior; Windows::Foundation::EventRegistrationToken m_networkBehaviorToken; bool m_meteredOverrideSet; }; } }