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
6 changes: 3 additions & 3 deletions apps/bare-expo/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3854,7 +3854,7 @@ SPEC CHECKSUMS:
EXUpdates: 83e4d666a085b44149f3b21d5bd057ad37b2c3e5
EXUpdatesInterface: 1436757deb0d574b84bba063bd024c315e0ec08b
FBLazyVector: 3a7ea85f6009224ad89f7daeda516f189e6b5759
hermes-engine: f631dcabc3dc2d46dc5f32c6c79d48d1d9e9aac6
hermes-engine: 6bb3000824be2770010ae038914fa26721255c8e
libavif: 84bbb62fb232c3018d6f1bab79beea87e35de7b7
libdav1d: 23581a4d8ec811ff171ed5e2e05cd27bad64c39f
libwebp: 02b23773aedb6ff1fd38cec7a77b81414c6842a8
Expand All @@ -3872,7 +3872,7 @@ SPEC CHECKSUMS:
React: 4bc1f928568ad4bcfd147260f907b4ea5873a03b
React-callinvoker: 8dd44c31888a314694efd0ef5f19ab7e0e855ef8
React-Core: 0c1f3042e1204c0512b2e4263062c66550d7e6a3
React-Core-prebuilt: baa77ffa5636202bd80ae54a374df8b194f96ed6
React-Core-prebuilt: 7894b037a2f0fa699a44de6c88d20acd4235b255
React-CoreModules: f6a626221d52f21b5eb8df2d79780b96f20240e5
React-cxxreact: 2e3990595049d43dd1d59ccd6cb35545f0dc6f03
React-debug: 60be0767f5672afc81bfd6a50d996507430f7906
Expand Down Expand Up @@ -3942,7 +3942,7 @@ SPEC CHECKSUMS:
ReactAppDependencyProvider: bfb12ead469222b022a2024f32aba47ce50de512
ReactCodegen: b9b0ea5c72e425fa5a89a031ada3e64dfd839771
ReactCommon: 0084791d25c4deae3d8b77efd4440fb2d5c38746
ReactNativeDependencies: c5e58d6ef1758f36ac4ee8b97949e0fb78f31b21
ReactNativeDependencies: 17a617edb4d5883a4c48339514ccb8b765f8af4f
RNCAsyncStorage: e85a99325df9eb0191a6ee2b2a842644c7eb29f4
RNCMaskedView: 3c9d7586e2b9bbab573591dcb823918bc4668005
RNCPicker: e0149590451d5eae242cf686014a6f6d808f93c7
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import expo.modules.notifications.notifications.channels.NotificationChannelMana
import expo.modules.notifications.permissions.NotificationPermissionsModule
import expo.modules.notifications.tokens.PushTokenModule
import expo.modules.print.PrintModule
import expo.modules.router.ExpoRouterModule
import expo.modules.screencapture.ScreenCaptureModule
import expo.modules.screenorientation.ScreenOrientationModule
import expo.modules.sensors.modules.AccelerometerModule
Expand Down Expand Up @@ -154,6 +155,7 @@ object ExperiencePackagePicker : ModulesProvider {
ExpoFetchModule::class.java to null,
FontUtilsModule::class.java to null,
ExpoLinkingModule::class.java to null,
ExpoRouterModule::class.java to null,
FileSystemModule::class.java to null,
FileSystemLegacyModule::class.java to null,
FontLoaderModule::class.java to null,
Expand Down
3 changes: 2 additions & 1 deletion apps/expo-go/android/settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ expoAutolinking.exclude = [
'@expo/ui',
'expo-mesh-gradient',
'@expo/app-integrity',
'@expo/home'
'@expo/home',
'expo-widgets'
]

expoAutolinking.useExpoModules()
Expand Down
4 changes: 0 additions & 4 deletions apps/expo-go/ios/Client/SwiftUI/HomeTabView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,9 @@ struct HomeTabView: View {
}
}
.onAppear {
viewModel.onViewWillAppear()
reviewManager.recordHomeAppear()
reviewManager.updateCounts(apps: viewModel.projects.count, snacks: viewModel.snacks.count)
}
.onDisappear {
viewModel.onViewDidDisappear()
}
.onChange(of: viewModel.projects.count) { _ in
reviewManager.updateCounts(apps: viewModel.projects.count, snacks: viewModel.snacks.count)
}
Expand Down
1 change: 1 addition & 0 deletions apps/expo-go/ios/Client/SwiftUI/Services/DataService.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright 2015-present 650 Industries. All rights reserved.

import Foundation

@MainActor
class DataService: ObservableObject {
@Published var projects: [ExpoProject] = []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import UIKit
class DevelopmentServerService: ObservableObject {
@Published var developmentServers: [DevelopmentServer] = []

private let discoveryInterval: TimeInterval = 2.0
private let discoveryInterval: TimeInterval = 3.0
private let remoteRefreshInterval: TimeInterval = 10.0
private let remoteCacheKey = "expo-dev-sessions-cache"
private var remoteFailureCount = 0
Expand Down Expand Up @@ -35,8 +35,8 @@ class DevelopmentServerService: ObservableObject {
}

func setSessionSecret(_ sessionSecret: String?) {
guard self.sessionSecret != sessionSecret else { return }
self.sessionSecret = sessionSecret
startRemoteRefreshLoop()
}

func refreshRemoteSessions() async {
Expand Down Expand Up @@ -125,36 +125,27 @@ class DevelopmentServerService: ObservableObject {
}

private func fetchLocalManifestInfo(url: String) async -> (name: String?, iconUrl: String?)? {
let manifestPaths = [
"\(url)/manifest",
"\(url)/manifest?platform=ios"
]

for manifestPath in manifestPaths {
guard let manifestURL = URL(string: manifestPath) else {
continue
}
guard let manifestURL = URL(string: "\(url)/manifest?platform=ios") else {
return nil
}

var request = URLRequest(url: manifestURL)
request.setValue("application/expo+json,application/json", forHTTPHeaderField: "Accept")
request.setValue("ios", forHTTPHeaderField: "Expo-Platform")
request.setValue("client", forHTTPHeaderField: "Expo-Client-Environment")
request.setValue(Versions.sharedInstance.sdkVersion, forHTTPHeaderField: "Expo-SDK-Version")

do {
let (data, response) = try await URLSession.shared.data(for: request)
guard let httpResponse = response as? HTTPURLResponse,
(200..<300).contains(httpResponse.statusCode) else {
continue
}
var request = URLRequest(url: manifestURL)
request.setValue("application/expo+json,application/json", forHTTPHeaderField: "Accept")
request.setValue("ios", forHTTPHeaderField: "Expo-Platform")
request.setValue("client", forHTTPHeaderField: "Expo-Client-Environment")
request.setValue(Versions.sharedInstance.sdkVersion, forHTTPHeaderField: "Expo-SDK-Version")

if let json = try JSONSerialization.jsonObject(with: data) as? [String: Any] {
if let parsed = parseManifestInfo(json: json, baseUrl: url) {
return parsed
}
}
} catch {}
}
do {
let (data, response) = try await URLSession.shared.data(for: request)
guard let httpResponse = response as? HTTPURLResponse,
(200..<300).contains(httpResponse.statusCode) else {
return nil
}

if let json = try JSONSerialization.jsonObject(with: data) as? [String: Any] {
return parseManifestInfo(json: json, baseUrl: url)
}
} catch {}

return nil
}
Expand Down
8 changes: 4 additions & 4 deletions apps/expo-go/ios/Exponent/Kernel/Core/EXKernel.m
Original file line number Diff line number Diff line change
Expand Up @@ -207,12 +207,12 @@ - (void)viewController:(__unused EXViewController *)vc didNavigateAppToVisible:(
[appStateModule setState:@"active"];
}
_visibleApp = appRecord;
[self _unregisterUnusedAppRecords];
} else {
_visibleApp = nil;
}

if (_visibleApp != nil) {
[self _unregisterUnusedAppRecords];
if (appRecordPreviouslyVisible) {
[_appRegistry unregisterAppWithRecord:appRecordPreviouslyVisible];
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,7 @@ - (void)handleFatalJSExceptionWithMessage:(nullable NSString *)message

[[EXKernel sharedInstance].serviceRegistry.errorRecoveryManager setError:error forScopeKey:_appRecord.scopeKey];

if ([self _isProdHome]) {
RCTFatal(error);
}
[_appRecord.viewController maybeShowError:error];
}

- (void)updateJSExceptionWithMessage:(nullable NSString *)message
Expand Down
4 changes: 0 additions & 4 deletions apps/expo-go/ios/Exponent/Kernel/Views/EXAppViewController.mm
Original file line number Diff line number Diff line change
Expand Up @@ -192,10 +192,6 @@ - (void)maybeShowError:(NSError *)error
dispatch_async(dispatch_get_main_queue(), ^{
[self _showErrorWithType:kEXFatalErrorTypeLoading error:error];
});
} else if ([domain isEqualToString:@"JSServer"] && [_appRecord.appManager enablesDeveloperTools]) {
// RCTRedBox already handled this
} else if ([domain rangeOfString:RCTErrorDomain].length > 0 && [_appRecord.appManager enablesDeveloperTools]) {
// RCTRedBox already handled this
} else {
dispatch_async(dispatch_get_main_queue(), ^{
[self _showErrorWithType:kEXFatalErrorTypeException error:error];
Expand Down
3 changes: 2 additions & 1 deletion apps/expo-go/ios/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ target 'Expo Go' do
'expo-splash-screen',
'@expo/ui',
'@expo/app-integrity',
'expo-brownfield'
'expo-brownfield',
'expo-widgets'
],
includeTests: true,
flags: {
Expand Down
2 changes: 1 addition & 1 deletion apps/expo-go/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4730,7 +4730,7 @@ SPEC CHECKSUMS:
GoogleAppMeasurement: 8a82b93a6400c8e6551c0bcd66a9177f2e067aed
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d
hermes-engine: 21f7021a3364f5f9dab02bdfd1fa0e21053e5dd5
hermes-engine: 452f2dd7422b2fd7973ae9ca103898d28d7744f0
libavif: 84bbb62fb232c3018d6f1bab79beea87e35de7b7
libdav1d: 23581a4d8ec811ff171ed5e2e05cd27bad64c39f
libwebp: 02b23773aedb6ff1fd38cec7a77b81414c6842a8
Expand Down
1 change: 1 addition & 0 deletions apps/native-component-list/metro.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ config.watchFolders = [
path.join(monorepoRoot, 'node_modules'), // Allow Metro to resolve "shared" `node_modules` of the monorepo
path.join(monorepoRoot, 'apps/common'), // Allow Metro to resolve common ThemeProvider
path.join(monorepoRoot, 'apps/bare-expo/modules/benchmarking'), // Allow Metro to resolve benchmarking folder
path.join(monorepoRoot, 'apps/bare-expo/modules/worklets-tester'), // Allow Metro to resolve worklets-tester folder
path.join(monorepoRoot, 'apps/test-suite'), // Allow Metro to resolve test-suite app
];

Expand Down
25 changes: 17 additions & 8 deletions docs/components/plugins/api/APISectionComponents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import {
CommentData,
GeneratedData,
PropsDefinitionData,
TypeSignaturesData,
TypeDefinitionData,
TypeSignaturesData,
} from './APIDataTypes';
import { buildCompoundNameByComponent } from './APISectionCompoundNames';
import { APISectionDeprecationNote } from './APISectionDeprecationNote';
import APISectionProps from './APISectionProps';
import {
Expand Down Expand Up @@ -88,7 +89,8 @@ const getComponentTypeParameters = ({
const renderComponent = (
{ name, comment, type, extendedTypes, children, signatures }: GeneratedData,
sdkVersion: string,
componentsProps?: PropsDefinitionData[]
componentsProps?: PropsDefinitionData[],
compoundNameByComponent?: Map<string, string>
) => {
const resolvedSignatures = getComponentSignatures({ signatures, type });
const resolvedType = getComponentType({ signatures: resolvedSignatures });
Expand All @@ -97,7 +99,8 @@ const renderComponent = (
extendedTypes,
signatures: resolvedSignatures,
});
const resolvedName = getComponentName(name, children);
const baseName = getComponentName(name, children);
const resolvedName = compoundNameByComponent?.get(baseName) ?? baseName;
const extractedComment = getComponentComment(comment, resolvedSignatures);

return (
Expand Down Expand Up @@ -128,16 +131,20 @@ const renderComponent = (
<APISectionProps
sdkVersion={sdkVersion}
data={componentsProps}
header={`${resolvedName}Props`}
header={`${baseName}Props`}
parentPlatforms={getAllTagData('platform', extractedComment)}
/>
) : null}
</div>
);
};

const APISectionComponents = ({ data, sdkVersion, componentsProps }: APISectionComponentsProps) =>
data?.length ? (
const APISectionComponents = ({ data, sdkVersion, componentsProps }: APISectionComponentsProps) => {
if (!data?.length) {
return null;
}
const compoundNameByComponent = buildCompoundNameByComponent(data);
return (
<>
<H2 key="components-header">{data.length === 1 ? 'Component' : 'Components'}</H2>
{data.map(component =>
Expand All @@ -146,10 +153,12 @@ const APISectionComponents = ({ data, sdkVersion, componentsProps }: APISectionC
sdkVersion,
componentsProps.filter(cp =>
getPossibleComponentPropsNames(component.name, component.children).includes(cp.name)
)
),
compoundNameByComponent
)
)}
</>
) : null;
);
};

export default APISectionComponents;
66 changes: 66 additions & 0 deletions docs/components/plugins/api/APISectionCompoundNames.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { GeneratedData, PropData, TypeDefinitionData, TypeDocKind } from './APIDataTypes';
import { buildCompoundNameByComponent } from './APISectionCompoundNames';

const makeComponentType = (propsName: string): TypeDefinitionData => ({
type: 'reference',
name: 'React.FC',
typeArguments: [{ type: 'reference', name: propsName }],
});

const makeProp = (name: string, type?: TypeDefinitionData, defaultValue?: string): PropData =>
({
name,
kind: TypeDocKind.Property,
type,
defaultValue,
}) as PropData;

const makeComponent = (name: string, propsName: string, children: PropData[] = []): GeneratedData =>
({
name,
kind: TypeDocKind.Class,
type: makeComponentType(propsName),
children,
}) as GeneratedData;

describe('buildCompoundNameByComponent', () => {
test('maps direct component properties to compound names', () => {
const menuItem = makeComponent('MenuItem', 'MenuItemProps');
const menu = makeComponent('Menu', 'MenuProps', [
makeProp('Item', makeComponentType('MenuItemProps')),
]);

const result = Object.fromEntries(buildCompoundNameByComponent([menu, menuItem]));

expect(result).toEqual({
MenuItem: 'Menu.Item',
});
});

test('chains compound names when parent is itself a compound component', () => {
const menuItemIcon = makeComponent('MenuItemIcon', 'MenuItemIconProps');
const menuItem = makeComponent('MenuItem', 'MenuItemProps', [
makeProp('Icon', makeComponentType('MenuItemIconProps')),
]);
const menu = makeComponent('Menu', 'MenuProps', [
makeProp('Item', makeComponentType('MenuItemProps')),
]);

const result = Object.fromEntries(buildCompoundNameByComponent([menu, menuItem, menuItemIcon]));

expect(result).toEqual({
MenuItem: 'Menu.Item',
MenuItemIcon: 'Menu.Item.Icon',
});
});

test('uses string default values as component targets', () => {
const tabs = makeComponent('Tabs', 'TabsProps', [makeProp('Tab', undefined, 'Tab')]);

const result = Object.fromEntries(buildCompoundNameByComponent([tabs]));

expect(result).toEqual({
Tab: 'Tabs.Tab',
});
});
});
Loading
Loading