Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 45 additions & 1 deletion vnext/ReactUWP/Modules/AppThemeModuleUwp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

namespace winrt {
using namespace Windows::UI::Xaml;
using namespace Windows::UI::ViewManagement;
}

namespace react { namespace uwp {
Expand All @@ -26,6 +27,17 @@ AppTheme::AppTheme(const std::shared_ptr<IReactInstance>& reactInstance, const s
, m_queueThread(defaultQueueThread)
{
m_currentTheme = winrt::Application::Current().RequestedTheme();
m_isHighContrast = m_accessibilitySettings.HighContrast();
m_highContrastColors = getHighContrastColors();

m_highContrastChangedRevoker = m_accessibilitySettings.HighContrastChanged(winrt::auto_revoke,
[this](const auto&, const auto&) {

folly::dynamic eventData = folly::dynamic::object("highContrastColors", getHighContrastColors())
("isHighContrast", getIsHighContrast());

fireEvent("highContrastChanged", std::move(eventData));
});

m_colorValuesChangedRevoker = m_uiSettings.ColorValuesChanged(winrt::auto_revoke,
[this](const auto&, const auto&) {
Expand All @@ -50,12 +62,44 @@ const std::string AppTheme::getCurrentTheme()
return m_currentTheme == winrt::ApplicationTheme::Light ? AppTheme::light : AppTheme::dark;
}

bool AppTheme::getIsHighContrast()
{
return m_accessibilitySettings.HighContrast();;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

; [](start = 48, length = 1)

nit: extra semicolon

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shoot, merged before the page fully loaded. Will fix this on next PR.

}

// Returns the RBG values for the 8 relevant High Contrast elements.
folly::dynamic AppTheme::getHighContrastColors() {
winrt::Windows::UI::Color ButtonFaceColor = m_uiSettings.UIElementColor(winrt::UIElementType::ButtonFace);
winrt::Windows::UI::Color ButtonTextColor = m_uiSettings.UIElementColor(winrt::UIElementType::ButtonText);
winrt::Windows::UI::Color GrayTextColor = m_uiSettings.UIElementColor(winrt::UIElementType::GrayText);
winrt::Windows::UI::Color HighlightColor = m_uiSettings.UIElementColor(winrt::UIElementType::Highlight);
winrt::Windows::UI::Color HighlightTextColor = m_uiSettings.UIElementColor(winrt::UIElementType::HighlightText);
winrt::Windows::UI::Color HotlightColor = m_uiSettings.UIElementColor(winrt::UIElementType::Hotlight);
winrt::Windows::UI::Color WindowColor = m_uiSettings.UIElementColor(winrt::UIElementType::Window);
winrt::Windows::UI::Color WindowTextColor = m_uiSettings.UIElementColor(winrt::UIElementType::WindowText);

folly::dynamic rbgValues = folly::dynamic::object("ButtonFaceColor", formatRGB(ButtonFaceColor))
("ButtonTextColor", formatRGB(ButtonTextColor))
("GrayTextColor", formatRGB(GrayTextColor))
("HighlightColor", formatRGB(HighlightColor))
("HighlightTextColor", formatRGB(HighlightTextColor))
("HotlightColor", formatRGB(HotlightColor))
("WindowColor", formatRGB(WindowColor))
("WindowTextColor", formatRGB(WindowTextColor));
return rbgValues;
}

std::string AppTheme::formatRGB(winrt::Windows::UI::Color ElementColor) {
char colorChars[8];
sprintf_s(colorChars, "#%02x%02x%02x", ElementColor.R, ElementColor.G, ElementColor.B);
return colorChars;
}

void AppTheme::fireEvent(std::string const& eventName, folly::dynamic&& eventData)
{
if (auto instance = m_wkReactInstance.lock())
{
instance->CallJsFunction("RCTDeviceEventEmitter", "emit", folly::dynamic::array(eventName, std::move(eventData)));
}
}

} } // namespace react::uwp
11 changes: 8 additions & 3 deletions vnext/ReactUWP/Modules/AppThemeModuleUwp.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,8 @@
#pragma once

#include <Modules/AppThemeModule.h>

#include <winrt/Windows.UI.ViewManagement.h>

#include <cxxreact/MessageQueueThread.h>

#include <IReactInstance.h>

namespace react { namespace uwp {
Expand All @@ -20,15 +17,23 @@ class AppTheme : public react::windows::AppTheme
virtual ~AppTheme();

const std::string getCurrentTheme() override;
bool getIsHighContrast() override;

private:
// High Contrast Color helper methods
folly::dynamic getHighContrastColors();
std::string formatRGB(winrt::Windows::UI::Color ElementColor);

void fireEvent(std::string const& eventName, folly::dynamic&& eventData);

std::weak_ptr<IReactInstance> m_wkReactInstance;
std::shared_ptr<facebook::react::MessageQueueThread> m_queueThread;
winrt::Windows::UI::Xaml::ApplicationTheme m_currentTheme{ winrt::Windows::UI::Xaml::ApplicationTheme::Light };
bool m_isHighContrast;
folly::dynamic m_highContrastColors;

winrt::Windows::UI::ViewManagement::AccessibilitySettings m_accessibilitySettings{ };
winrt::Windows::UI::ViewManagement::AccessibilitySettings::HighContrastChanged_revoker m_highContrastChangedRevoker{ };
winrt::Windows::UI::ViewManagement::UISettings m_uiSettings{ };
winrt::Windows::UI::ViewManagement::UISettings::ColorValuesChanged_revoker m_colorValuesChangedRevoker{ };
};
Expand Down
14 changes: 13 additions & 1 deletion vnext/ReactWindowsCore/Modules/AppThemeModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ const std::string AppTheme::getCurrentTheme()
return AppTheme::light;
}

bool AppTheme::getIsHighContrast()
{
return false;
}

folly::dynamic AppTheme::getHighContrastColors()
{
return {};
}

//
// AppThemeModule
//
Expand All @@ -31,7 +41,9 @@ AppThemeModule::AppThemeModule(std::shared_ptr<AppTheme>&& appTheme)
auto AppThemeModule::getConstants() -> std::map<std::string, folly::dynamic>
{
return {
{ "initialAppTheme", folly::dynamic { m_appTheme->getCurrentTheme() } }
{ "initialAppTheme", folly::dynamic { m_appTheme->getCurrentTheme() } },
{ "initialHighContrast", folly::dynamic { m_appTheme->getIsHighContrast() }},
{ "initialHighContrastColors", folly::dynamic {m_appTheme->getHighContrastColors()}}
};
}

Expand Down
4 changes: 3 additions & 1 deletion vnext/ReactWindowsCore/Modules/AppThemeModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ class AppTheme
virtual ~AppTheme();

virtual const std::string getCurrentTheme();
virtual bool getIsHighContrast();
virtual folly::dynamic getHighContrastColors();
};

class AppThemeModule : public facebook::xplat::module::CxxModule
Expand All @@ -29,7 +31,7 @@ class AppThemeModule : public facebook::xplat::module::CxxModule
AppThemeModule(std::shared_ptr<AppTheme> && appTheme);

// CxxModule
std::string getName() override { return name; }
std::string getName() override { return name; };
auto getConstants() -> std::map<std::string, folly::dynamic> override;
auto getMethods() -> std::vector<Method> override;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,20 @@
'use strict';

import { NativeEventEmitter } from 'react-native';
import { IHighContrastColors } from './AppThemeTypes';

class AppThemeModule extends NativeEventEmitter {
get currentTheme(): string {
return '';
}

get isHighContrast(): boolean {
return false;
}

get currentHighContrastColorValues(): IHighContrastColors {
return { } as IHighContrastColors;
}
}

export const AppTheme = new AppThemeModule();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,27 @@

import { NativeEventEmitter, NativeModules } from 'react-native';
const MissingNativeEventEmitterShim = require('MissingNativeEventEmitterShim');
import { IHighContrastColors, IHighContrastChangedEvent } from './AppThemeTypes';

const NativeAppTheme = NativeModules.RTCAppTheme;

class AppThemeModule extends NativeEventEmitter {
public isAvailable: boolean;
private _isHighContrast: boolean;
private _currentTheme: string;
private _highContrastColors: IHighContrastColors;

constructor() {
super(NativeAppTheme);
this.isAvailable = true;

this._highContrastColors = NativeAppTheme.initialHighContrastColors;
this._isHighContrast = NativeAppTheme.initialHighContrast;
this.addListener('highContrastChanged', (nativeEvent: IHighContrastChangedEvent) => {
this._isHighContrast = nativeEvent.isHighContrast;
this._highContrastColors = nativeEvent.highContrastColors;
});

this._currentTheme = NativeAppTheme.initialAppTheme;
this.addListener('appThemeChanged', ({currentTheme}:{currentTheme: string}) => {
this._currentTheme = currentTheme;
Expand All @@ -24,13 +34,23 @@ class AppThemeModule extends NativeEventEmitter {
get currentTheme(): string {
return this._currentTheme;
}

get isHighContrast(): boolean {
return this._isHighContrast;
}

get currentHighContrastColors(): IHighContrastColors {
return this._highContrastColors;
}
}

// This module depends on the native `RCTAppTheme` module. If you don't include it,
// `AppTheme.isAvailable` will return `false`, and any method calls will throw.
class MissingNativeAppThemeShim extends MissingNativeEventEmitterShim {
public isAvailable = false;
public currentTheme = '';
public isHighContrast = false;
public currentHighContrastColors = {} as IHighContrastColors;
}

export const AppTheme = (NativeAppTheme ? new AppThemeModule() : new MissingNativeAppThemeShim());
Expand Down
22 changes: 22 additions & 0 deletions vnext/src/Libraries/AppTheme/AppThemeTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

export interface IHighContrastColors {
ButtonFaceColor: string;
ButtonTextColor: string;
GrayTextColor: string;
HighlightColor: string;
HighlightTextColor: string;
HotlightColor: string;
WindowColor: string;
WindowTextColor: string;
}

export interface IAppThemeChangedEvent {
currentTheme: string;
}

export interface IHighContrastChangedEvent {
isHighContrast: boolean;
highContrastColors: IHighContrastColors;
}
13 changes: 0 additions & 13 deletions vnext/src/Libraries/Modules/AppTheme/__mocks__/AppTheme.uwp.ts

This file was deleted.

Loading