Skip to content
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

chore: move system-theme-extractor to i-static-page/modules/theme #1116

Merged
merged 20 commits into from
Feb 14, 2024
Merged
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ Changelog

_Note: Gaps between patch versions are faulty, broken or test releases._

## v4.0.0-beta.?? (2023-??-??)

#### :house: Internal

* Moved `system-theme-extractor` from `core` to `components/super/i-static-page/modules/theme`

## v4.0.0-beta.54 (2024-02-06)

#### :bug: Bug Fix
Expand All @@ -23,7 +29,7 @@ _Note: Gaps between patch versions are faulty, broken or test releases._

* The entry threshold for counting an element as visible is set to the minimum value `components/base/b-virtual-scroll-new`

## v4.0.0-beta.53 (2024-01-31)
## v4.0.0-beta.53 (2023-01-31)

#### :rocket: New Feature

Expand Down
8 changes: 5 additions & 3 deletions src/components/super/i-static-page/i-static-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { setLocale, locale } from 'core/i18n';

import type { AppliedRoute, InitialRoute } from 'core/router';
import * as cookie from 'core/kv-storage/engines/cookie';
import { webEngineFactory } from 'core/system-theme-extractor/engines/web';
import WebEngine from 'components/super/i-static-page/modules/theme/system-theme-extractor/engines/web/engine';

import {

Expand Down Expand Up @@ -100,8 +100,10 @@ export default abstract class iStaticPage extends iPage {
*/
@system<iStaticPage>((o) => themeManagerFactory(
o,
cookie.syncLocalStorage,
webEngineFactory(o)
{
themeStorageEngine: cookie.syncLocalStorage,
systemThemeExtractor: new WebEngine(o)
}
))

readonly theme: CanUndef<ThemeManager>;
Expand Down
42 changes: 37 additions & 5 deletions src/components/super/i-static-page/modules/theme/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,24 @@ module.exports = config.createConfig({dirs: [__dirname, 'client']}, {

## Accessors

## current
### availableThemes

A set of available app themes.

```typescript
import iBlock, { component, prop, field } from 'components/super/i-block/i-block';

@component()
export default class bExample extends iBlock {
created() {
console.log(this.r.theme.availableThemes);
}
}
```

## Methods

### get

Current theme value.

Expand All @@ -103,22 +120,37 @@ import iBlock, { component, prop, field } from 'components/super/i-block/i-block
@component()
export default class bExample extends iBlock {
created() {
console.log(this.r.theme.current);
console.log(this.r.theme.get());
}
}
```

## availableThemes
### set

A set of available app themes.
Sets a new value for the current theme

```typescript
import iBlock, { component, prop, field } from 'components/super/i-block/i-block';

@component()
export default class bExample extends iBlock {
changeTheme(value: 'dark' | 'light') {
this.r.theme.set(value);
}
}
```

### useSystem

Sets the actual system theme and activates the system theme change listener

```typescript
import iBlock, { component, prop, field } from 'components/super/i-block/i-block';

@component()
export default class bExample extends iBlock {
created() {
console.log(this.r.theme.availableThemes);
this.r.theme.useSystem();
}
}
```
16 changes: 8 additions & 8 deletions src/components/super/i-static-page/modules/theme/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,22 @@
* https://github.com/V4Fire/Client/blob/master/LICENSE
*/

import type { StorageEngine } from 'core/kv-storage';

import type iBlock from 'components/super/i-block/i-block';
import ThemeManager from 'components/super/i-static-page/modules/theme/theme-manager';
import type { StorageEngine } from 'core/kv-storage';
import type { SystemThemeExtractor } from 'core/system-theme-extractor';

import type { SystemThemeExtractor } from 'components/super/i-static-page/modules/theme/system-theme-extractor';

/**
* Returns an instance of the class for managing interface themes, if that functionality is available
* Returns an instance of the class for managing interface themes if that functionality is available
*
* @param component
* @param store
* @param systemTheme
* @param engines
*/
export default function themeManagerFactory(
component: iBlock,
store: StorageEngine,
systemTheme: SystemThemeExtractor
engines: {themeStorageEngine: StorageEngine; systemThemeExtractor: SystemThemeExtractor}
): CanNull<ThemeManager> {
return Object.isString(THEME) ? new ThemeManager(component, store, systemTheme) : null;
return Object.isString(THEME) ? new ThemeManager(component, engines) : null;
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ Changelog
> - :house: [Internal]
> - :nail_care: [Polish]

## v4.0.0-beta.?? (2023-??-??)

#### :house: Internal

* Moved from `core` to `components/super/i-static-page/modules/theme`

## v4.0.0-beta.52 (2023-01-31)

#### :rocket: New Feature
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# core/system-theme-extractor
# components/super/i-static-page/modules/theme/system-theme-extractor

This module provides an API for obtaining and observing the preferred color scheme of an application.

Expand All @@ -9,12 +9,12 @@ By default, the engine for the web is supported.
The engine needs to be passed to the `themeManager` constructor.

```ts
import { webEngineFactory } from 'core/system-theme-extractor/engines/web';
import WebEngine from 'components/super/i-static-page/modules/theme/system-theme-extractor/engines/web/engine';

class iRoot extends iStaticPage {
@system<iStaticPage>((o) => themeManagerFactory(
// ...other required parameters for themeManager
webEngineFactory(o)
new WebEngine(o)
))

readonly theme: CanUndef<ThemeManager>;
Expand All @@ -24,16 +24,16 @@ class iRoot extends iStaticPage {
Also, you can implement your own engine.

```ts
// src/core/system-theme-extractor/engines/custom/index.ts
import type { SystemThemeExtractor } from 'core/system-theme-extractor';
// src/components/super/i-static-page/modules/theme/system-theme-extractor/engines/custom/index.ts
import type { SystemThemeExtractor } from 'components/super/i-static-page/modules/theme/system-theme-extractor';

export default class CustomEngine implements SystemThemeExtractor {
// Implement all necessary methods of the interface here.
}
```

The `SystemThemeExtractor` interface specifies that the `getSystemTheme` method
should return a promise-like object so that you can compute the system theme asynchronously.
should return a promise object so that you can compute the system theme asynchronously.
If synchronous computation is relevant in your case, you can use `SyncPromise`.

See `components/super/i-static-page/modules/theme` for details
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*!
* V4Fire Client Core
* https://github.com/V4Fire/Client
*
* Released under the MIT license
* https://github.com/V4Fire/Client/blob/master/LICENSE
*/

import type { EventEmitterLikeP, AsyncOptions } from 'core/async';
import SyncPromise from 'core/promise/sync';

import type { SystemThemeExtractor } from 'components/super/i-static-page/modules/theme/system-theme-extractor';
import Friend from 'components/friends/friend';
import type iBlock from 'components/super/i-block/i-block';

/**
* Represents a `SystemThemeExtractor` implementation tailored for web environments.
* This implementation uses a media query to monitor changes in the preferred color scheme.
*/
export default class WebEngine extends Friend implements SystemThemeExtractor {
/**
* Media query to watch theme changes
*/
protected darkThemeMq: MediaQueryList;

/**
* Event emitter
*/
protected emitter: EventEmitterLikeP;

constructor(component: iBlock) {
super(component);
this.darkThemeMq = globalThis.matchMedia('(prefers-color-scheme: dark)');
this.emitter = <EventEmitterLikeP>((...args: [string, (e: Event) => void]) => {
this.darkThemeMq.addEventListener(...args);
return (...args: [string, (e: Event) => void]) => this.darkThemeMq.removeEventListener(...args);
});
}

/** @inheritDoc */
getSystemTheme(): SyncPromise<string> {
return SyncPromise.resolve(this.darkThemeMq.matches ? 'dark' : 'light');
}

/** @inheritDoc */
onThemeChange(cb: (value: string) => void, asyncOptions?: AsyncOptions): void {
const
changeHandler = (e: MediaQueryListEvent) => cb(e.matches ? 'dark' : 'light');

this.ctx.async.on(this.emitter, 'change', changeHandler, asyncOptions);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@
* https://github.com/V4Fire/Client/blob/master/LICENSE
*/

export * from 'core/system-theme-extractor/interface';
export * from 'components/super/i-static-page/modules/theme/system-theme-extractor/interface';
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,24 @@
* https://github.com/V4Fire/Client/blob/master/LICENSE
*/

import type { AsyncOptions } from 'core/async/modules/base/interface';

/**
* API for retrieving and monitoring the system's visual appearance.
* An API for retrieving and monitoring the system's visual appearance
*/
export interface SystemThemeExtractor {
/**
* Retrieves the current system visual appearance theme.
* Retrieves the current system visual appearance theme
*/
getSystemTheme(): PromiseLike<string>;
getSystemTheme(): Promise<string>;

/**
* Initializes an event listener for changes in the system's visual appearance theme.
* Initializes an event listener for changes in the system's visual appearance theme
*
* @param cb - A callback function to be invoked when the theme changes.
* It receives the color scheme identifier as a string parameter by which project theme can be selected
*/
subscribe(cb: (value: string) => void): void;

/**
* Terminates the event listener for changes in the system's visual appearance theme.
* It receives the color scheme identifier as a string parameter by which project theme can be selected.
*
* @param [asyncOptions]
*/
unsubscribe(): void;
onThemeChange(cb: (value: string) => void, asyncOptions?: AsyncOptions): void;
}
Loading
Loading