environment manager (#1784)

This PR extracts the environment manager from #1778.

### Change Type

- [x] `major` — Breaking change

### Release Notes

- [editor] Move environment flags to environment manager
This commit is contained in:
Steve Ruiz 2023-08-02 12:05:09 +01:00 committed by GitHub
parent 79fae186e4
commit c478d75117
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 69 additions and 54 deletions

View file

@ -630,6 +630,7 @@ export class Editor extends EventEmitter<TLEventMap> {
// (undocumented)
duplicateShapes(ids: TLShapeId[], offset?: VecLike): this;
get editingShapeId(): null | TLShapeId;
readonly environment: EnvironmentManager;
get erasingShapeIds(): TLShapeId[];
get erasingShapeIdsSet(): Set<TLShapeId>;
// @internal (undocumented)
@ -805,12 +806,8 @@ export class Editor extends EventEmitter<TLEventMap> {
isAncestorSelected(id: TLShapeId): boolean;
// (undocumented)
isAncestorSelected(shape: TLShape): boolean;
readonly isAndroid: boolean;
readonly isChromeForIos: boolean;
readonly isFirefox: boolean;
isIn(path: string): boolean;
isInAny(...paths: string[]): boolean;
readonly isIos: boolean;
get isMenuOpen(): boolean;
isPointInShape(shape: TLShape, point: VecLike, opts?: {
margin?: number;
@ -821,7 +818,6 @@ export class Editor extends EventEmitter<TLEventMap> {
margin?: number;
hitInside?: boolean;
}): boolean;
readonly isSafari: boolean;
isShapeInPage(shape: TLShape, pageId?: TLPageId): boolean;
// (undocumented)
isShapeInPage(shapeId: TLShapeId, pageId?: TLPageId): boolean;

View file

@ -103,6 +103,7 @@ import { arrowBindingsIndex } from './derivations/arrowBindingsIndex'
import { parentsToChildren } from './derivations/parentsToChildren'
import { deriveShapeIdsInCurrentPage } from './derivations/shapeIdsInCurrentPage'
import { ClickManager } from './managers/ClickManager'
import { EnvironmentManager } from './managers/EnvironmentManager'
import { HistoryManager } from './managers/HistoryManager'
import { SnapManager } from './managers/SnapManager'
import { TextManager } from './managers/TextManager'
@ -239,19 +240,7 @@ export class Editor extends EventEmitter<TLEventMap> {
this.root.children![Tool.id] = new Tool(this, this.root)
}
if (typeof window !== 'undefined' && 'navigator' in window) {
this.isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent)
this.isIos = !!navigator.userAgent.match(/iPad/i) || !!navigator.userAgent.match(/iPhone/i)
this.isChromeForIos = /crios.*safari/i.test(navigator.userAgent)
this.isFirefox = /firefox/i.test(navigator.userAgent)
this.isAndroid = /android/i.test(navigator.userAgent)
} else {
this.isSafari = false
this.isIos = false
this.isChromeForIos = false
this.isFirefox = false
this.isAndroid = false
}
this.environment = new EnvironmentManager(this)
this.store.onBeforeDelete = (record) => {
if (record.typeName === 'shape') {
@ -412,39 +401,11 @@ export class Editor extends EventEmitter<TLEventMap> {
readonly textMeasure: TextManager
/**
* Whether the editor is running in Safari.
* A manager for the editor's environment.
*
* @public
*/
readonly isSafari: boolean
/**
* Whether the editor is running on iOS.
*
* @public
*/
readonly isIos: boolean
/**
* Whether the editor is running on iOS.
*
* @public
*/
readonly isChromeForIos: boolean
/**
* Whether the editor is running on Firefox.
*
* @public
*/
readonly isFirefox: boolean
/**
* Whether the editor is running on Android.
*
* @public
*/
readonly isAndroid: boolean
readonly environment: EnvironmentManager
/**
* The current HTML element containing the editor.

View file

@ -0,0 +1,54 @@
import { Editor } from '../Editor'
export class EnvironmentManager {
constructor(public editor: Editor) {
if (typeof window !== 'undefined' && 'navigator' in window) {
this.isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent)
this.isIos = !!navigator.userAgent.match(/iPad/i) || !!navigator.userAgent.match(/iPhone/i)
this.isChromeForIos = /crios.*safari/i.test(navigator.userAgent)
this.isFirefox = /firefox/i.test(navigator.userAgent)
this.isAndroid = /android/i.test(navigator.userAgent)
} else {
this.isSafari = false
this.isIos = false
this.isChromeForIos = false
this.isFirefox = false
this.isAndroid = false
}
}
/**
* Whether the editor is running in Safari.
*
* @public
*/
readonly isSafari: boolean
/**
* Whether the editor is running on iOS.
*
* @public
*/
readonly isIos: boolean
/**
* Whether the editor is running on iOS.
*
* @public
*/
readonly isChromeForIos: boolean
/**
* Whether the editor is running on Firefox.
*
* @public
*/
readonly isFirefox: boolean
/**
* Whether the editor is running on Android.
*
* @public
*/
readonly isAndroid: boolean
}

View file

@ -7,7 +7,11 @@ export function useCoarsePointer() {
// This is a workaround for a Firefox bug where we don't correctly
// detect coarse VS fine pointer. For now, let's assume that you have a fine
// pointer if you're on Firefox on desktop.
if (editor.isFirefox && !editor.isAndroid && !editor.isIos) {
if (
editor.environment.isFirefox &&
!editor.environment.isAndroid &&
!editor.environment.isIos
) {
editor.updateInstanceState({ isCoarsePointer: false })
return
}

View file

@ -495,7 +495,7 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
// eslint-disable-next-line react-hooks/rules-of-hooks
const changeIndex = React.useMemo<number>(() => {
return this.editor.isSafari ? (globalRenderIndex += 1) : 0
return this.editor.environment.isSafari ? (globalRenderIndex += 1) : 0
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [shape])

View file

@ -250,7 +250,7 @@ function PatternFillDefForCanvas() {
const { defs, isReady } = usePattern()
useEffect(() => {
if (isReady && editor.isSafari) {
if (isReady && editor.environment.isSafari) {
const htmlLayer = findHtmlLayerParent(containerRef.current!)
if (htmlLayer) {
// Wait for `patternContext` to be picked up

View file

@ -379,7 +379,7 @@ export const PageMenu = function PageMenu() {
item={page}
listSize={pages.length}
onRename={() => {
if (editor.isIos) {
if (editor.environment.isIos) {
const name = window.prompt('Rename page', page.name)
if (name && name !== page.name) {
editor.renamePage(page.id, name)

View file

@ -156,10 +156,10 @@ export function usePrint() {
}
function triggerPrint() {
if (editor.isChromeForIos) {
if (editor.environment.isChromeForIos) {
beforePrintHandler()
window.print()
} else if (editor.isSafari) {
} else if (editor.environment.isSafari) {
beforePrintHandler()
document.execCommand('print', false)
} else {