From be5833388499e6723232d8fc604591cb4aaf94c0 Mon Sep 17 00:00:00 2001 From: shirakaba <14055146+shirakaba@users.noreply.github.com> Date: Wed, 23 Nov 2022 15:57:47 +0900 Subject: [PATCH] fix: clean up Application types --- .../core/accessibility/font-scale.android.ts | 3 +- .../core/application/application-common.ts | 19 +++++------ .../application/application-interfaces.ts | 34 +++++++++++++++---- packages/core/application/index.android.ts | 2 +- packages/core/application/index.d.ts | 15 +++----- packages/core/application/index.ios.ts | 5 ++- 6 files changed, 47 insertions(+), 31 deletions(-) diff --git a/packages/core/accessibility/font-scale.android.ts b/packages/core/accessibility/font-scale.android.ts index c8112ba25f..efe18c172b 100644 --- a/packages/core/accessibility/font-scale.android.ts +++ b/packages/core/accessibility/font-scale.android.ts @@ -1,3 +1,4 @@ +import type { ApplicationEventData } from '../application'; import * as Application from '../application'; import { FontScaleCategory, getClosestValidFontScale } from './font-scale-common'; export * from './font-scale-common'; @@ -12,7 +13,7 @@ function fontScaleChanged(origFontScale: number) { eventName: Application.fontScaleChangedEvent, object: Application, newValue: currentFontScale, - }); + } as ApplicationEventData); } } diff --git a/packages/core/application/application-common.ts b/packages/core/application/application-common.ts index 7667bc3283..da9c762d97 100644 --- a/packages/core/application/application-common.ts +++ b/packages/core/application/application-common.ts @@ -4,7 +4,6 @@ import '../globals'; // Types import { AndroidApplication, iOSApplication } from '.'; import { CssChangedEventData, DiscardedErrorEventData, LoadAppCSSEventData, UnhandledErrorEventData } from './application-interfaces'; -import type { EventData, Observable } from '../data/observable'; import { View } from '../ui/core/view'; // Requires @@ -50,10 +49,10 @@ export function setResources(res: any) { export const android: AndroidApplication = undefined; export const ios: iOSApplication = undefined; -export const on = global.NativeScriptGlobals.events.on.bind(global.NativeScriptGlobals.events) as Observable['on']; -export const off = global.NativeScriptGlobals.events.off.bind(global.NativeScriptGlobals.events) as Observable['off']; -export const notify = global.NativeScriptGlobals.events.notify.bind(global.NativeScriptGlobals.events) as Observable['notify']; -export const hasListeners = global.NativeScriptGlobals.events.hasListeners.bind(global.NativeScriptGlobals.events) as Observable['hasListeners']; +export const on = global.NativeScriptGlobals.events.on.bind(global.NativeScriptGlobals.events) as typeof import('.')['on']; +export const off = global.NativeScriptGlobals.events.off.bind(global.NativeScriptGlobals.events) as typeof import('.')['off']; +export const notify = global.NativeScriptGlobals.events.notify.bind(global.NativeScriptGlobals.events) as typeof import('.')['notify']; +export const hasListeners = global.NativeScriptGlobals.events.hasListeners.bind(global.NativeScriptGlobals.events) as typeof import('.')['hasListeners']; let app: iOSApplication | AndroidApplication; export function setApplication(instance: iOSApplication | AndroidApplication): void { @@ -63,7 +62,7 @@ export function setApplication(instance: iOSApplication | AndroidApplication): v } export function livesync(rootView: View, context?: ModuleContext) { - global.NativeScriptGlobals.events.notify({ eventName: 'livesync', object: app }); + notify({ eventName: 'livesync', object: app }); const liveSyncCore = global.__onLiveSyncCore; let reapplyAppStyles = false; @@ -85,7 +84,7 @@ export function livesync(rootView: View, context?: ModuleContext) { export function setCssFileName(cssFileName: string) { cssFile = cssFileName; - global.NativeScriptGlobals.events.notify({ + notify({ eventName: 'cssChanged', object: app, cssFile: cssFileName, @@ -98,7 +97,7 @@ export function getCssFileName(): string { export function loadAppCss(): void { try { - global.NativeScriptGlobals.events.notify({ + notify({ eventName: 'loadAppCss', object: app, cssFile: getCssFileName(), @@ -181,7 +180,7 @@ export function setSuspended(value: boolean): void { } global.__onUncaughtError = function (error: NativeScriptError) { - global.NativeScriptGlobals.events.notify({ + notify({ eventName: uncaughtErrorEvent, object: app, android: error, @@ -191,7 +190,7 @@ global.__onUncaughtError = function (error: NativeScriptError) { }; global.__onDiscardedError = function (error: NativeScriptError) { - global.NativeScriptGlobals.events.notify({ + notify({ eventName: discardedErrorEvent, object: app, error: error, diff --git a/packages/core/application/application-interfaces.ts b/packages/core/application/application-interfaces.ts index 13ea7fa5c5..2a4524e316 100644 --- a/packages/core/application/application-interfaces.ts +++ b/packages/core/application/application-interfaces.ts @@ -13,22 +13,45 @@ export interface NativeScriptError extends Error { } export interface ApplicationEventData extends EventData { + /** + * UIApplication or undefined, unless otherwise specified. Prefer explicit + * properties where possible. + */ ios?: any; + /** + * androidx.appcompat.app.AppCompatActivity or undefined, unless otherwise + * specified. Prefer explicit properties where possible. + */ android?: any; - eventName: string; + /** + * Careful with this messy type. A significant refactor is needed to make it + * strictly extend EventData['object'], which is an Observable. It's used in + * various ways: + * - By font-scale: the Application module, typeof import('.') + * - Within index.android.ts: AndroidApplication + * - Within index.ios.ts: iOSApplication + */ object: any; } export interface LaunchEventData extends ApplicationEventData { + /** + * The value stored into didFinishLaunchingWithOptions notification's + * userInfo under 'UIApplicationLaunchOptionsLocalNotificationKey'; + * otherwise, null. + */ + ios: unknown; root?: View | null; savedInstanceState?: any /* android.os.Bundle */; } export interface OrientationChangedEventData extends ApplicationEventData { + android: any /* globalAndroid.app.Application */; newValue: 'portrait' | 'landscape' | 'unknown'; } export interface SystemAppearanceChangedEventData extends ApplicationEventData { + android: any /* globalAndroid.app.Application */; newValue: 'light' | 'dark'; } @@ -42,15 +65,14 @@ export interface DiscardedErrorEventData extends ApplicationEventData { error: NativeScriptError; } -export interface CssChangedEventData extends EventData { +export interface CssChangedEventData extends ApplicationEventData { cssFile?: string; cssText?: string; } -export interface AndroidActivityEventData { +export interface AndroidActivityEventData extends ApplicationEventData { activity: any /* androidx.appcompat.app.AppCompatActivity */; - eventName: string; - object: any; + object: any /* AndroidApplication */; } export interface AndroidActivityBundleEventData extends AndroidActivityEventData { @@ -84,6 +106,6 @@ export interface RootViewControllerImpl { contentController: any; } -export interface LoadAppCSSEventData extends EventData { +export interface LoadAppCSSEventData extends ApplicationEventData { cssFile: string; } diff --git a/packages/core/application/index.android.ts b/packages/core/application/index.android.ts index f02dfbbeb6..9f94029c97 100644 --- a/packages/core/application/index.android.ts +++ b/packages/core/application/index.android.ts @@ -4,7 +4,7 @@ import { AndroidActivityBackPressedEventData, AndroidActivityBundleEventData, An // TODO: explain why we need to this or remov it // Use requires to ensure order of imports is maintained -const appCommon = require('./application-common'); +const appCommon = require('./application-common') as typeof import('./application-common'); // First reexport so that app module is initialized. export * from './application-common'; diff --git a/packages/core/application/index.d.ts b/packages/core/application/index.d.ts index 32da824030..b2df5010b0 100644 --- a/packages/core/application/index.d.ts +++ b/packages/core/application/index.d.ts @@ -257,7 +257,7 @@ export function _resetRootView(entry?: NavigationEntry | string); /** * Removes listener for the specified event name. */ -export function off(eventNames: string, callback?: (eventData: EventData) => void, thisArg?: any, options?: EventListenerOptions | boolean): void; +export function off(eventNames: string, callback?: (eventData: ApplicationEventData) => void, thisArg?: any, options?: EventListenerOptions | boolean): void; /** * Shortcut alias to the removeEventListener method. @@ -266,13 +266,13 @@ export function off(eventNames: string, callback?: (eventData: EventData) => voi * @param thisArg - An optional parameter which will be used as `this` context for callback execution. * @param options An optional parameter. If passed as a boolean, configures the useCapture value. Otherwise, specifies options. */ -export function off(eventNames: string, callback?: (eventData: EventData) => void, thisArg?: any, options?: EventListenerOptions | boolean): void; +export function off(eventNames: string, callback?: (eventData: ApplicationEventData) => void, thisArg?: any, options?: EventListenerOptions | boolean): void; /** * Notifies all the registered listeners for the event provided in the data.eventName. * @param data The data associated with the event. */ -export function notify(data: any): void; +export function notify(data: T, options?: CustomEventInit): void; /** * Checks whether a listener is registered for the specified event name. @@ -297,18 +297,13 @@ export function on(event: 'cssChanged', callback: (args: CssChangedEventData) => /** * Event raised then livesync operation is performed. */ -export function on(event: 'livesync', callback: (args: EventData) => void, thisArg?: any, options?: AddEventListenerOptions | boolean): void; +export function on(event: 'livesync', callback: (args: ApplicationEventData) => void, thisArg?: any, options?: AddEventListenerOptions | boolean): void; /** * This event is raised when application css is changed. */ export function on(event: 'cssChanged', callback: (args: CssChangedEventData) => void, thisArg?: any, options?: AddEventListenerOptions | boolean): void; -/** - * Event raised then livesync operation is performed. - */ -export function on(event: 'livesync', callback: (args: EventData) => void, thisArg?: any, options?: AddEventListenerOptions | boolean): void; - /** * This event is raised on application launchEvent. */ @@ -319,7 +314,7 @@ export function on(event: 'launch', callback: (args: LaunchEventData) => void, t * Its intent is to be suitable for measuring app startup times. * @experimental */ -export function on(event: 'displayed', callback: (args: EventData) => void, thisArg?: any, options?: AddEventListenerOptions | boolean): void; +export function on(event: 'displayed', callback: (args: ApplicationEventData) => void, thisArg?: any, options?: AddEventListenerOptions | boolean): void; /** * This event is raised when the Application is suspended. diff --git a/packages/core/application/index.ios.ts b/packages/core/application/index.ios.ts index 23ab08e053..b81a43f873 100644 --- a/packages/core/application/index.ios.ts +++ b/packages/core/application/index.ios.ts @@ -4,7 +4,7 @@ import { ApplicationEventData, CssChangedEventData, LaunchEventData, LoadAppCSSE // TODO: explain why we need to this or remov it // Use requires to ensure order of imports is maintained -const { backgroundEvent, displayedEvent, exitEvent, foregroundEvent, getCssFileName, launchEvent, livesync, lowMemoryEvent, notify, on, orientationChanged, orientationChangedEvent, resumeEvent, setApplication, suspendEvent, systemAppearanceChanged, systemAppearanceChangedEvent } = require('./application-common'); +const { backgroundEvent, displayedEvent, exitEvent, foregroundEvent, getCssFileName, launchEvent, livesync, lowMemoryEvent, notify, on, orientationChanged, orientationChangedEvent, resumeEvent, setApplication, suspendEvent, systemAppearanceChanged, systemAppearanceChangedEvent } = require('./application-common') as typeof import('./application-common'); // First reexport so that app module is initialized. export * from './application-common'; @@ -12,7 +12,6 @@ import { View } from '../ui/core/view'; import { NavigationEntry } from '../ui/frame/frame-interfaces'; // TODO: Remove this and get it from global to decouple builder for angular import { Builder } from '../ui/builder'; -import { Observable } from '../data/observable'; import { CSSUtils } from '../css/system-classes'; import { IOSHelper } from '../ui/core/view/view-helper'; import { Device } from '../platform'; @@ -238,7 +237,7 @@ export class iOSApplication implements iOSApplicationDefinition { const args: LaunchEventData = { eventName: launchEvent, object: this, - ios: (notification && notification.userInfo && notification.userInfo.objectForKey('UIApplicationLaunchOptionsLocalNotificationKey')) || null, + ios: notification?.userInfo?.objectForKey('UIApplicationLaunchOptionsLocalNotificationKey') || null, }; notify(args);