Initial commit: code as received (Create/Anything export)
Insole-production time tracker exported from the Create/Anything AI platform. Baseline snapshot before any reverse-engineering or cleanup. - apps/mobile: Expo Router app (iOS/Android/web), the only workspace - publisher/: standalone OpenNext/AWS deploy tooling for the web side - Backend (/api/tasks, /api/logs + DB) lives remotely, not in this repo
This commit is contained in:
1
apps/mobile/polyfills/shared/empty-component.tsx
Normal file
1
apps/mobile/polyfills/shared/empty-component.tsx
Normal file
@@ -0,0 +1 @@
|
||||
export default () => null;
|
||||
99
apps/mobile/polyfills/shared/expo-image.tsx
Normal file
99
apps/mobile/polyfills/shared/expo-image.tsx
Normal file
@@ -0,0 +1,99 @@
|
||||
import type { ImageProps } from 'expo-image';
|
||||
import * as ExpoImage from 'expo-image';
|
||||
import { Buffer } from 'buffer';
|
||||
import React, { forwardRef, useState, useEffect, useCallback, useRef } from 'react';
|
||||
import { Platform } from 'react-native';
|
||||
|
||||
function buildGridPlaceholder(w: number, h: number): string {
|
||||
const size = Math.max(w, h);
|
||||
const svg = `
|
||||
<svg width="${size}" height="${size}" viewBox="0 0 895 895" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="895" height="895" rx="19" fill="#E9E7E7"/>
|
||||
<g stroke="#C0C0C0" stroke-width="1.00975">
|
||||
<line x1="447.505" y1="-23" x2="447.505" y2="901"/>
|
||||
<line x1="889.335" y1="447.505" x2="5.66443" y2="447.505"/>
|
||||
<line x1="889.335" y1="278.068" x2="5.66443" y2="278.068"/>
|
||||
<line x1="889.335" y1="57.1505" x2="5.66443" y2="57.1504"/>
|
||||
<line x1="61.8051" y1="883.671" x2="61.8051" y2="0.000061"/>
|
||||
<line x1="282.495" y1="907" x2="282.495" y2="-30"/>
|
||||
<line x1="611.495" y1="907" x2="611.495" y2="-30"/>
|
||||
<line x1="832.185" y1="883.671" x2="832.185" y2="0.000061"/>
|
||||
<line x1="889.335" y1="827.53" x2="5.66443" y2="827.53"/>
|
||||
<line x1="889.335" y1="606.613" x2="5.66443" y2="606.612"/>
|
||||
<line x1="4.3568" y1="4.6428" x2="889.357" y2="888.643"/>
|
||||
<line x1="-0.3568" y1="894.643" x2="894.643" y2="0.642772"/>
|
||||
<circle cx="447.5" cy="441.5" r="163.995"/>
|
||||
<circle cx="447.911" cy="447.911" r="237.407"/>
|
||||
<circle cx="448" cy="442" r="384.495"/>
|
||||
</g>
|
||||
</svg>`;
|
||||
const b64 = Buffer.from(svg).toString('base64');
|
||||
return `data:image/svg+xml;base64,${b64}`;
|
||||
}
|
||||
|
||||
type Src = ImageProps['source'];
|
||||
function computeSourceKey(src: Src): string {
|
||||
if (Array.isArray(src)) return src.map(computeSourceKey).join('|');
|
||||
if (typeof src === 'number') return String(src); // require('./img.png')
|
||||
if (typeof src === 'string') return src; // remote on web
|
||||
if (src && typeof src === 'object' && 'uri' in src) return src.uri ?? '';
|
||||
return '';
|
||||
}
|
||||
|
||||
const WrappedImage = forwardRef<ExpoImage.Image, ImageProps>(function WrappedImage(props, ref) {
|
||||
const [fallbackSource, setFallbackSource] = useState<Src | null>(null);
|
||||
const source = props.source;
|
||||
const onError = props.onError;
|
||||
const style = props.style;
|
||||
const currentKey = computeSourceKey(props.source);
|
||||
const prevKeyRef = useRef(currentKey);
|
||||
|
||||
useEffect(() => {
|
||||
if (prevKeyRef.current !== currentKey) {
|
||||
// parent really pointed to a different image: clear any old fallback
|
||||
setFallbackSource(null);
|
||||
prevKeyRef.current = currentKey;
|
||||
}
|
||||
}, [currentKey]);
|
||||
const handleError: ImageProps['onError'] = useCallback(
|
||||
(e: ExpoImage.ImageErrorEventData) => {
|
||||
onError?.(e);
|
||||
|
||||
/* already swapped or dealing with a multi‑src array */
|
||||
if (fallbackSource || Array.isArray(source)) return;
|
||||
|
||||
// prevent it from recursing
|
||||
if (
|
||||
source &&
|
||||
typeof source === 'object' &&
|
||||
'uri' in source &&
|
||||
source?.uri?.startsWith('data:')
|
||||
) {
|
||||
return;
|
||||
}
|
||||
/* try to infer a sensible grid size */
|
||||
const finalStyle = Array.isArray(style) ? Object.assign({}, ...style) : style;
|
||||
const width = finalStyle?.width ?? 128;
|
||||
const height = finalStyle?.height ?? 128;
|
||||
|
||||
if (Platform.OS === 'web') {
|
||||
setFallbackSource({ uri: buildGridPlaceholder(width, height) });
|
||||
} else {
|
||||
setFallbackSource(require('../../src/__create/placeholder.svg'));
|
||||
}
|
||||
},
|
||||
[source, fallbackSource, onError, style]
|
||||
);
|
||||
|
||||
return (
|
||||
<ExpoImage.Image {...props} source={fallbackSource ?? source} ref={ref} onError={handleError} />
|
||||
);
|
||||
});
|
||||
|
||||
/* expose static helpers so nothing breaks */
|
||||
Object.assign(WrappedImage, ExpoImage);
|
||||
|
||||
/* re‑export everything that expo-image provides */
|
||||
export * from 'expo-image';
|
||||
export const Image = WrappedImage;
|
||||
export default Image;
|
||||
Reference in New Issue
Block a user