-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Implement AppearanceModule #4622
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
ac3f7fe
e5a38e7
2939562
0e791d4
83625fb
e2dd07c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| { | ||
| "type": "prerelease", | ||
| "comment": "Implement AppearanceModule", | ||
| "packageName": "react-native-windows", | ||
| "email": "ngerlem@microsoft.com", | ||
| "dependentChangeType": "patch", | ||
| "date": "2020-04-16T15:41:54.563Z" | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the MIT License. | ||
|
|
||
| #include "pch.h" | ||
| #include "AppearanceModule.h" | ||
|
|
||
| #include <winrt/Windows.UI.ViewManagement.h> | ||
|
|
||
| using Application = winrt::Windows::UI::Xaml::Application; | ||
| using ApplicationTheme = winrt::Windows::UI::Xaml::ApplicationTheme; | ||
| using UISettings = winrt::Windows::UI::ViewManagement::UISettings; | ||
|
|
||
| using Method = facebook::xplat::module::CxxModule::Method; | ||
|
|
||
| namespace react::uwp { | ||
|
|
||
| AppearanceChangeListener::AppearanceChangeListener(std::weak_ptr<IReactInstance> &&reactInstance) noexcept | ||
| : Mso::ActiveObject<>(Mso::DispatchQueue::MainUIQueue()), m_weakReactInstance(std::move(reactInstance)) { | ||
| // Ensure we're constructed on the UI thread | ||
| VerifyIsInQueueElseCrash(); | ||
|
|
||
| m_currentTheme = Application::Current().RequestedTheme(); | ||
|
|
||
| // UISettings will notify us on a background thread regardless of where we construct it or register for events. | ||
| // Redirect callbacks to the UI thread where we can check app theme. | ||
| m_revoker = m_uiSettings.ColorValuesChanged( | ||
| winrt::auto_revoke, [weakThis{Mso::WeakPtr(this)}](const auto & /*sender*/, const auto & /*args*/) noexcept { | ||
| if (auto strongThis = weakThis.GetStrongPtr()) { | ||
| strongThis->InvokeInQueueStrong([strongThis]() noexcept { strongThis->OnColorValuesChanged(); }); | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| const char *AppearanceChangeListener::GetColorScheme() const noexcept { | ||
| return ToString(m_currentTheme); | ||
| } | ||
|
|
||
| const char *AppearanceChangeListener::ToString(ApplicationTheme theme) noexcept { | ||
| return theme == ApplicationTheme::Dark ? "dark" : "light"; | ||
| } | ||
|
|
||
| void AppearanceChangeListener::OnColorValuesChanged() noexcept { | ||
| auto newTheme = Application::Current().RequestedTheme(); | ||
| if (m_currentTheme != newTheme) { | ||
| m_currentTheme = newTheme; | ||
|
|
||
| if (auto reactInstance = m_weakReactInstance.lock()) { | ||
| reactInstance->CallJsFunction( | ||
| "RCTDeviceEventEmitter", "emit", folly::dynamic::array("appearanceChanged", ToString(m_currentTheme))); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| AppearanceModule::AppearanceModule(Mso::CntPtr<AppearanceChangeListener> &&appearanceListener) noexcept | ||
| : m_changeListener(std::move(appearanceListener)) {} | ||
|
|
||
| std::string AppearanceModule::getName() { | ||
| return AppearanceModule::Name; | ||
| } | ||
|
|
||
| std::vector<Method> AppearanceModule::getMethods() { | ||
| return {Method( | ||
| "getColorScheme", [this](folly::dynamic /*args*/) { return m_changeListener->GetColorScheme(); }, SyncTag)}; | ||
| } | ||
|
|
||
| } // namespace react::uwp | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the MIT License. | ||
|
|
||
| #pragma once | ||
|
|
||
| #include <activeObject/activeObject.h> | ||
| #include <cxxreact/CxxModule.h> | ||
| #include <eventWaitHandle/eventWaitHandle.h> | ||
|
|
||
| #include "IReactInstance.h" | ||
|
|
||
| namespace react::uwp { | ||
|
|
||
| // Listens for the current theme on the UI thread, storing the most recent. Will emit JS events on Appearance change. | ||
| class AppearanceChangeListener final : public Mso::ActiveObject<> { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a very weird
In the end, we basically just use |
||
| using ApplicationTheme = winrt::Windows::UI::Xaml::ApplicationTheme; | ||
| using UISettings = winrt::Windows::UI::ViewManagement::UISettings; | ||
|
|
||
| public: | ||
| AppearanceChangeListener(std::weak_ptr<IReactInstance> &&reactInstance) noexcept; | ||
| const char *GetColorScheme() const noexcept; | ||
|
|
||
| private: | ||
| static const char *ToString(ApplicationTheme theme) noexcept; | ||
| void OnColorValuesChanged() noexcept; | ||
|
|
||
| UISettings m_uiSettings; | ||
| UISettings::ColorValuesChanged_revoker m_revoker; | ||
| std::atomic<ApplicationTheme> m_currentTheme; | ||
| std::weak_ptr<IReactInstance> m_weakReactInstance; | ||
| }; | ||
|
|
||
| class AppearanceModule final : public facebook::xplat::module::CxxModule { | ||
| public: | ||
| static constexpr const char *Name = "Appearance"; | ||
|
|
||
| AppearanceModule(Mso::CntPtr<AppearanceChangeListener> &&appearanceListener) noexcept; | ||
| std::string getName() override; | ||
| std::vector<Method> getMethods() override; | ||
|
|
||
NickGerleman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| private: | ||
| Mso::CntPtr<AppearanceChangeListener> m_changeListener; | ||
| }; | ||
|
|
||
| } // namespace react::uwp | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,7 @@ | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the MIT License. | ||
|
|
||
| #pragma once | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not related, just noticed this was missing |
||
| #include <cxxreact/CxxModule.h> | ||
|
|
||
| namespace facebook { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -65,6 +65,7 @@ | |
| </ImportGroup> | ||
| <ImportGroup Label="Shared"> | ||
| <Import Project="..\Chakra\Chakra.vcxitems" Label="Shared" /> | ||
| <Import Project="..\Mso\Mso.vcxitems" Label="Shared" /> | ||
| <Import Project="..\Shared\Shared.vcxitems" Label="Shared" /> | ||
| </ImportGroup> | ||
| <ImportGroup Label="PropertySheets"> | ||
|
|
@@ -77,6 +78,8 @@ | |
| <ItemDefinitionGroup> | ||
| <ClCompile> | ||
| <PrecompiledHeader>Use</PrecompiledHeader> | ||
| <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> | ||
| <ForcedIncludeFiles>pch.h</ForcedIncludeFiles> | ||
| <CompileAsWinRT>false</CompileAsWinRT> | ||
| <SDLCheck>true</SDLCheck> | ||
| <!-- | ||
|
|
@@ -106,7 +109,7 @@ | |
| $(ReactNativeWindowsDir); | ||
| $(ReactNativeWindowsDir)Common; | ||
| $(ReactNativeWindowsDir)JSI\Shared; | ||
| $(ReactNativeWindowsDir)Pch; | ||
| $(ReactNativeWindowsDir)ReactUwp\Pch; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Good catch! nit: Please keep the original folder name spelling: ReactUWP.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Going to go ahead and merge as is since we will be nuking the project soonish anyway. |
||
| $(ReactNativeWindowsDir)ReactUWP\GeneratedWinmdHeader; | ||
| $(ReactNativeWindowsDir)ReactWindowsCore; | ||
| $(ReactNativeWindowsDir)ReactWindowsCore\tracing; | ||
|
|
@@ -180,6 +183,7 @@ | |
| <ClInclude Include="Modules\Animated\SpringAnimationDriver.h" /> | ||
| <ClInclude Include="Modules\Animated\TrackingAnimatedNode.h" /> | ||
| <ClInclude Include="..\include\ReactUWP\TurboModuleUtils.h" /> | ||
| <ClInclude Include="Modules\AppearanceModule.h" /> | ||
| <ClInclude Include="Threading\BatchingUIMessageQueueThread.h" /> | ||
| <ClInclude Include="Threading\MessageQueueThreadFactory.h" /> | ||
| <ClInclude Include="Utils\StandardControlResourceKeyNames.h" /> | ||
|
|
@@ -275,6 +279,7 @@ | |
| <ClCompile Include="Modules\Animated\CalculatedAnimationDriver.cpp" /> | ||
| <ClCompile Include="Modules\Animated\SpringAnimationDriver.cpp" /> | ||
| <ClCompile Include="Modules\Animated\TrackingAnimatedNode.cpp" /> | ||
| <ClCompile Include="Modules\AppearanceModule.cpp" /> | ||
| <ClCompile Include="Threading\BatchingUIMessageQueueThread.cpp" /> | ||
| <ClCompile Include="Threading\MessageQueueThreadFactory.cpp" /> | ||
| <ClCompile Include="TurboModule\TurboModuleUtils.cpp" /> | ||
|
|
@@ -452,4 +457,4 @@ | |
| <RemoveDir Directories="$(IdlHeaderDirectory)" ContinueOnError="true" /> | ||
| <RemoveDir Directories="$(UnmergedWinmdDirectory)" ContinueOnError="true" /> | ||
| </Target> | ||
| </Project> | ||
| </Project> | ||
Uh oh!
There was an error while loading. Please reload this page.