Browse Source

Browser implementation

Max Katz 2 years ago
parent
commit
70dcf71910

+ 26 - 0
src/Browser/Avalonia.Browser/BrowserPlatformSettings.cs

@@ -0,0 +1,26 @@
+using Avalonia.Browser.Interop;
+using Avalonia.Platform;
+
+namespace Avalonia.Browser;
+
+internal class BrowserPlatformSettings : DefaultPlatformSettings
+{
+    private bool _isDarkMode;
+    
+    public BrowserPlatformSettings()
+    {
+        _isDarkMode = DomHelper.ObserveDarkMode(m =>
+        {
+            _isDarkMode = m;
+            OnColorValuesChanged(GetColorValues());
+        });
+    }
+    
+    public override PlatformColorValues GetColorValues()
+    {
+        return base.GetColorValues() with
+        {
+            ThemeVariant = _isDarkMode ? PlatformThemeVariant.Dark : PlatformThemeVariant.Light
+        };
+    }
+}

+ 5 - 0
src/Browser/Avalonia.Browser/BrowserTopLevelImpl.cs

@@ -228,6 +228,11 @@ namespace Avalonia.Browser
 
         public IKeyboardDevice KeyboardDevice { get; } = BrowserWindowingPlatform.Keyboard;
         public WindowTransparencyLevel TransparencyLevel { get; private set; }
+        public void SetFrameThemeVariant(PlatformThemeVariant themeVariant)
+        {
+            // not in the standard, but we potentially can use "apple-mobile-web-app-status-bar-style" for iOS and "theme-color" for android.
+        }
+
         public AcrylicPlatformCompensationLevels AcrylicCompensationLevels { get; }
 
         public ITextInputMethodImpl TextInputMethod => _avaloniaView;

+ 5 - 0
src/Browser/Avalonia.Browser/Interop/DomHelper.cs

@@ -25,4 +25,9 @@ internal static partial class DomHelper
     public static partial double ObserveDpi(
        [JSMarshalAs<JSType.Function<JSType.Number, JSType.Number>>]
         Action<double, double> onDpiChanged);
+    
+    [JSImport("AvaloniaDOM.observeDarkMode", AvaloniaModule.MainModuleName)]
+    public static partial bool ObserveDarkMode(
+        [JSMarshalAs<JSType.Function<JSType.Boolean>>]
+        Action<bool> onDpiChanged);
 }

+ 1 - 1
src/Browser/Avalonia.Browser/WindowingPlatform.cs

@@ -39,7 +39,7 @@ namespace Avalonia.Browser
                 .Bind<IClipboard>().ToSingleton<ClipboardImpl>()
                 .Bind<ICursorFactory>().ToSingleton<CssCursorFactory>()
                 .Bind<IKeyboardDevice>().ToConstant(s_keyboard)
-                .Bind<IPlatformSettings>().ToSingleton<DefaultPlatformSettings>()
+                .Bind<IPlatformSettings>().ToSingleton<BrowserPlatformSettings>()
                 .Bind<IPlatformThreadingInterface>().ToConstant(instance)
                 .Bind<IRenderLoop>().ToConstant(new RenderLoop())
                 .Bind<IRenderTimer>().ToConstant(ManualTriggerRenderTimer.Instance)

+ 13 - 0
src/Browser/Avalonia.Browser/webapp/modules/avalonia/dom.ts

@@ -3,6 +3,19 @@ export class AvaloniaDOM {
         element.classList.add(className);
     }
 
+    static observeDarkMode(observer: (isDarkMode: boolean) => boolean): boolean {
+        if (globalThis.matchMedia === undefined) {
+            return false;
+        }
+
+        const media = globalThis.matchMedia("(prefers-color-scheme: dark)");
+        media.addEventListener("change", (args: MediaQueryListEvent) => {
+            observer(args.matches);
+        });
+
+        return media.matches;
+    }
+
     static createAvaloniaHost(host: HTMLElement) {
         const randomIdPart = Math.random().toString(36).replace(/[^a-z]+/g, "").substr(2, 10);