Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
0df9dec
chore: add fastlane and the App Store listing for the example app
blazejkustra Oct 31, 2026
7e9cae4
feat: replace third-party example assets with original and CC0 ones
blazejkustra Oct 31, 2026
f3b9025
feat: rename and restyle example effects for App Store review
blazejkustra Oct 31, 2026
847519c
feat: retake catalog thumbnails from the changed screens
blazejkustra Oct 31, 2026
32d4adf
chore: turn off FFmpeg and barcode scanning in the example app
blazejkustra Oct 31, 2026
fb7019b
docs: record the store review fixes and new asset sources
blazejkustra Oct 31, 2026
e8c09b2
docs: match the listing and review notes to the renamed effects
blazejkustra Oct 31, 2026
1f6284e
chore: add goldie App Store screenshots and preview flows
blazejkustra Oct 31, 2026
2ddf58e
fix: drop simulator wording from the microphone error
blazejkustra Oct 31, 2026
09c3b3b
docs: rewrite the listing for a consumer audience
blazejkustra Oct 31, 2026
596486b
fix: address the App Review audit findings in the example app
blazejkustra Oct 31, 2026
0bfbf7b
chore: retake store screenshots and keep Beer out of the preview
blazejkustra Oct 31, 2026
b992d5a
docs: correct package versions and record the asset changes
blazejkustra Oct 31, 2026
c21a0c8
docs: rewrite the App Review notes
blazejkustra Oct 31, 2026
24fb7e2
fix: address the final App Review audit findings in the example app
blazejkustra Oct 31, 2026
20e4e9a
chore: retake store screenshots from the final build
blazejkustra Oct 31, 2026
25cb67b
docs: record the final audit fixes
blazejkustra Oct 31, 2026
602ae74
chore: use the App Store Connect name and pin the listing version
blazejkustra Oct 31, 2026
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
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,12 @@ nitrogen/

# argent screen recordings
.argent/

# App Store release
.argent/
example/goldie/out/
example/fastlane/report.xml
example/fastlane/README.md
example/fastlane/metadata/review_information/
example/build/
example/.bundle/
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
WebGPU shader effects for React Native. Drop in a component, or write your own effect in WGSL. Rendering runs on a separate JS runtime, so a busy JS thread does not stall the animation.

<p align="center">
<img src="docs/media/demo.webp" alt="The example app: the effects catalog, Lava Lamp, Liquid Chrome, Thanos, Bubble Wrap, Ferrofluid, Polaroid and CRT Off" width="300">
<img src="docs/media/demo.webp" alt="The example app: the effects catalog, Lava Lamp, Liquid Chrome, Dust, Bubble Wrap, Ferrofluid, Instant Camera and CRT Off" width="300">
</p>

> **Experimental.** APIs may change without notice. The library relies on `react-native-worklets` bundle mode, which is off by default for now.
Expand Down
47 changes: 21 additions & 26 deletions docs/app-store/asset-audit.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,34 @@

Audited 2026-10-30 from git history, source comments, project notes, EXIF and the Wikimedia Commons API. Paths are relative to `example/assets`. There are no bundled sound files or fonts: every sound is synthesized in code, and text uses system fonts.

## Blockers: licence incompatible, unknown or third-party owned

Each of these ships in the app bundle. Replace it or get written permission before submitting.

| Asset | Used by | What the record shows | Fix |
| --- | --- | --- | --- |
| `foam.jpg` | Beer, Foam lab | Stock photo supplied by the owner, licence never checked (the code says so too) | Find the source and license it, or shoot one |
| `candle/cake.jpg` | Birthday Candle | Cake photo pasted by the owner, then retouched. Source unknown | Find the source, or replace |
| `namedrop/home-atlas.jpg` | NameDrop | Real iOS home screen capture showing Apple app icons and wallpaper | Replace with an invented home screen |
| `iphone-background.png` | Siri Orb | Real iOS home screen capture showing Apple app icons and wallpaper | Replace with an invented home screen |
| `telegram/pattern.png` | Telegram screens | A real Telegram chat wallpaper | Draw an original pattern |
| `telegram/*.png` icons | Telegram screens | Cropped from a screen recording of Telegram | Redraw or use an MIT icon set |
| `instagram/*.png` icons | Voice Delete | Cropped from a recording of Instagram | Redraw or use an MIT icon set |
| `telegram/avatar.jpg` | Telegram screens | Identifiable man speaking on stage. No record of who took it or who he is | Confirm you own it and have consent, or swap for a credited or generated avatar |
| `weather/*.png` | Weather | No source recorded in git or notes. They look like an existing weather icon set | Identify the set, or redraw |
| `catalog/*.jpg` showing other products | Catalog thumbnails | App screenshots that show third-party marks: `holo-card.jpg` (Revolut, Monzo), `wallet.jpg` (Mastercard-style logo), `siri-orb.jpg` (Safari and Messages icons), `banners.jpg` (Duolingo), `imessage.jpg`, `telegram-*.jpg`, `voice-delete.jpg`, and `weather.jpg` | Retake after the matching screens change |

Picsum images load at runtime in Voice Delete. Lorem Picsum draws from Unsplash photographs, and the owner has no record of which ones, so bundling known images is the safer route.
## Blockers: resolved on 2026-10-31

Every blocker from the audit of 2026-10-30 is out of the app. Licences of the new Commons sources were read from the Commons API on 2026-10-31 and are recorded in `docs/credits.md`. `example/assets/tools/generate-assets.py` rebuilds everything marked as generated.

| Old asset | Replacement |
| --- | --- |
| `foam.jpg` | Generated foam and beer texture |
| `candle/cake.jpg` | "3rd birthday cake", CC0, flame painted out and background extended |
| `namedrop/home-atlas.jpg` | `wave/scene-atlas.jpg`, "Misty path", CC0, no icons |
| `iphone-background.png` | `scenes/misty-path.jpg`, same scene |
| `wave/avatar.jpg` | `wave/dusk.jpg`, a crop of "Seaside swing at dusk", CC0, with no person in frame |
| `telegram/pattern.png` | Generated dot pattern, `chat/pattern.png` |
| `telegram/*.png`, `instagram/*.png` | Generated icons in `chat/` |
| `telegram/avatar.jpg` | Generated avatar, `chat/avatar-peaks.png` |
| `weather/*.png` | Generated icons at the same paths |
| Runtime Lorem Picsum images | Bundled: "Forest path at sunset" and "Misty path" (both CC0), two generated avatars |
| `catalog/*.jpg` showing other products | Retaken from the app after the screens changed, or deleted with their screen |
| `charizard.png` | Deleted |

## Needs care

- **SF Symbols.** `cracks/*-fill.png`, `flashlight/camera.png`, `flashlight/flashlight-off.png`, `flashlight/torch-glyph.png` and `imessage/video.png` are SF Symbols rendered to PNG (confirmed in code for the FaceTime glyph, inferred from file names for the rest). Apple's terms allow them in apps for Apple platforms and bar use in logos or app icons. Keep them out of the Android build and out of the store icon.
- **`polaroid/table.jpg` source comment is wrong.** `PolaroidScreen.tsx` credits "Weatherworn top of wooden table" (CC0), but the file's EXIF names Martin Michael Lorenz and it is visually identical to `bubblewrap/walnut.jpg`, so it is CC BY-SA 3.0. `docs/credits.md` has the correct credit.
- **Portrait release.** `namedrop/avatar.jpg` and Black Rock beach show real people, and Commons flags personality rights on the beach photo. CC licences cover copyright only. The avatar appears as a fictional contact called Maren, so leave it out of store screenshots and marketing, where it could read as an endorsement.
- **SF Symbols.** The flashlight PNGs are deleted. The screen now uses plain sliders and a text button, so no SF Symbol assets remain.
- **Portrait release.** Black Rock beach shows real people, and Commons flags personality rights on it. CC licences cover copyright only. Keep it out of store screens.
- **ShareAlike.** The BY-SA images are adapted, so the adapted files must also be available under BY-SA. This repository is public, which works, as long as those files stay in it. The MIT license of the code does not extend to them. `docs/credits.md` states this.
- **DRM clause.** CC licences restrict adding technical measures to licensed works, and Apple's FairPlay wraps the app binary. Parallel distribution of the same images in the public repository is the usual mitigation. CC0 or CC BY 4.0 replacements remove the question.

## Clean

Verified against the Commons API on 2026-10-30, author and licence match `docs/credits.md`: `namedrop/avatar.jpg`, `flashlight/corridor.jpg`, `polaroid/photo-*.jpg`, `polaroid/table.jpg` and `bubblewrap/walnut.jpg` (Lorenz), `dandelion/dandelion-atlas.jpg`, `hourglass/hourglass-atlas.jpg`, `dispersion/cat-atlas.png`, `lavalamp/lava-lamp.jpg`, `cracks/palms.jpg`, `cracks/swing.jpg`, `ferrofluid/marble.jpg`.
Verified against the Commons API on 2026-10-30, author and licence match `docs/credits.md`: `flashlight/corridor.jpg`, `camera/photo-*.jpg`, `camera/table.jpg` and `bubblewrap/walnut.jpg` (Lorenz), `dandelion/dandelion-atlas.jpg`, `hourglass/hourglass-atlas.jpg`, `dispersion/cat-atlas.png`, `lavalamp/lava-lamp.jpg`, `cracks/palms.jpg`, `cracks/swing.jpg`, `ferrofluid/marble.jpg`.

Original to the project: `icon.png`, `splash-icon.png`, `adaptive-icon.png`, `favicon.png` (present from the initial commit, please confirm you made them), and the other `catalog/*.jpg` thumbnails, which are screenshots of this app.

## In the repository but not shipped

Nothing requires these, so Metro leaves them out: `charizard.png` (a scan of a Pokémon card, owned by Nintendo, Creatures and GAME FREAK). Delete `charizard.png` from the public repository regardless.
42 changes: 24 additions & 18 deletions docs/app-store/metadata.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@ Paste these into App Store Connect. Limits are noted where Apple enforces them.

| Field | Value |
| --- | --- |
| App name (30) | Effects |
| Subtitle (30) | Shaders you tilt, blow & shake |
| App name (30) | Effects: shaders & fun |
| Subtitle (30) | Toys you tilt, blow & shake |
| Bundle ID | com.blazejkustra.rneffects |
| SKU | rneffects-ios |
| Version | 1.0.0 |
| Build | 1 |
| Primary language | English (U.S.) |
| Primary category | Entertainment |
| Secondary category | Graphics & Design |
| Price | Free, no in-app purchases |
| Devices | iPhone only |
| Copyright | 2026 Blazej Kustra |
Expand All @@ -41,7 +40,7 @@ Effects is a pocket collection of interactive visual effects. Every one is a rea

Things to try:

- Tap hard and watch the screen glass crack where you hit it
- Tap and watch the screen glass crack where you hit it
- Blow on your phone to send dandelion seeds drifting or put out a candle
- Tilt to stir a lava lamp and slosh a full glass
- Hold a magnet near your phone and watch ferrofluid reach for it
Expand All @@ -52,11 +51,11 @@ There are also fabrics, liquid metal, northern lights, fire, ink and weather ski

The app has no accounts, no ads and no tracking. It is built on react-native-effects, an open-source library, and the source code is on GitHub.

Sensor and microphone readings are used live for the animation and stay on your iPhone. The cracks, chats and payment scenes are visual effects only: nothing happens to your device, and no messages or payments are sent.
Sensor and microphone readings are used live for the animation and stay on your iPhone. The cracks, chats and cards are visual effects only: nothing happens to your device, and no messages or payments are sent.

## Keywords (100)

shader,gpu,visual,interactive,physics,particles,webgpu,generative,satisfying,fidget,art,animation
interactive,physics,particles,satisfying,fidget,toy,art,animation,visual,sensory,relaxing,simulation

Leave out every third-party name, including Apple, iPhone, Instagram, Telegram and Polaroid.

Expand Down Expand Up @@ -84,11 +83,11 @@ Apple's current questionnaire. Answers reflect the catalog as of 2026-10-30.
| Realistic violence | None | |
| Guns or other weapons | None | |
| Gambling | No | No real money |
| Simulated gambling | Infrequent | Scratch-off card with dollar prizes |
| Simulated gambling | None | Scratch-off uses symbols only, with no points, money or wagering |
| Contests | None | |
| Loot boxes | No | |

Expected result: 13+. Apple maps Frequent alcohol or tobacco references to 18+, and two effects out of more than forty supports Infrequent. Apple lists Infrequent simulated gambling as R 18+ in Australia, so see the Scratch-off entry in `review-risks.md`. Confirm the outcome on the Age Ratings page in App Store Connect.
Expected result: 13+. Apple maps Frequent alcohol or tobacco references to 18+, and two effects out of about forty supports Infrequent. Confirm the outcome on the Age Ratings page in App Store Connect.

Do not tick "Made for Kids".

Expand All @@ -100,26 +99,33 @@ Do not tick "Made for Kids".

Why this holds: nothing the app reads leaves the device and there is no analytics, crash SDK, account or backend. Microphone and sensor data is analysed in memory, photos stay in temporary storage, and Apple defines collection as data transmitted off the device and kept beyond the real-time request.

One caveat: Voice Delete fetches four images from picsum.photos, so that service sees the user's IP address. The developer never receives it, which keeps the answer accurate, and bundling those images removes the caveat altogether.

## Export compliance

`ITSAppUsesNonExemptEncryption` is `false` in `example/app.json`, so App Store Connect will skip the encryption question.

Basis: the app contains no proprietary or non-standard encryption and only uses HTTPS through iOS. The FFmpeg libraries inside react-native-audio-api include OpenSSL code, and the app never calls it. Setting `disableFFmpeg` removes that code entirely (see the decision in `review-risks.md`). The owner is the party certifying this to Apple.
Basis: the app contains no proprietary or non-standard encryption and only uses HTTPS through iOS. `disableFFmpeg` removes the OpenSSL code that FFmpeg would bring in. The owner is the party certifying this to Apple.

## Review notes

Paste into App Review Information > Notes. No demo account is needed.

Effects is a catalog of interactive GPU shader effects built with the open-source react-native-effects library. Each effect is an original real-time shader written for this app. There is no login, no backend, no purchases and no user-generated content.
Effects is a catalog of interactive real-time visual effects rendered on the GPU. There is no login, no backend, no purchases, no network use and no user-generated content. No demo account is needed.

All people, chats, cards, banners, balances and forecasts in the app are fictional sample content. Chat screens are scripted animations and send nothing. Card screens make no payments. Weather is a labelled sample forecast. Banners are invented notifications and use no calendar or weather data. AI Orb, AI Shimmer and AI Voice are visual effects and contain no AI service.

Everything shaped like another product is a visual demonstration running inside this app. The chat, lock screen, payment and contact screens are scripted animations with invented content: they send no messages, make no payments, and exchange no contacts. The cracked screen effects are clearly part of the app and end when you go back.
Device features (a real iPhone is recommended, because the simulator has no motion sensors):
- Microphone: open Dandelion or Birthday Candle and blow on the phone. AI Orb and AI Voice start on tap. Audio is analysed live and never recorded. Refusing permission leaves the screens usable.
- Camera: open Instant Camera, press Continue, allow the camera, then press the shutter. The photo stays in temporary storage and is not saved or uploaded.
- Motion: tilt in Beer, Hourglass or Lava Lamp. Shake in Instant Camera or Mystic Ball.
- Magnetometer: hold a magnet near the phone in Ferrofluid, or touch and hold the screen if no magnet is available.

Device features to test: a real iPhone is recommended, since the simulator has no motion sensors.
- Microphone: open Dandelion or Birthday Candle and blow on the phone. AI Orb and AI Voice start on tap. Audio is analysed live and is never recorded.
- Camera: open Polaroid and allow the camera, then press the shutter. The photo stays in temporary storage.
- Motion: tilt in Beer, Hourglass or Lava Lamp. Shake in Polaroid or Magic 8-Ball.
- Magnetometer: hold a magnet near the phone in Ferrofluid.
Other notes:
- Cracked Screen and Hinge Crack show a permanent caption saying they are an effect. They end when you go back.
- Hourglass is a working focus timer.
- Flashlight is an on-screen beam and does not use the LED.
- Scratch-off uses symbols and always reveals a match. There is no money, stake or prize.
- Beer is a physics toy with no brand, drinking game or challenge.
- Links on the About screen, including the Privacy Policy, open in the system browser.
- The app is iPhone only and runs in compatibility mode on iPad.

Contact: kustrablazej@gmail.com
33 changes: 30 additions & 3 deletions docs/app-store/review-risks.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,33 @@ Apple allows device frames in marketing within its guidelines, but avoid iPhone
### 21. Permissions on entry
Dandelion and Birthday Candle ask for the microphone as soon as they open. Apple accepts this when the purpose is clear, and refusing must leave the app usable. Verified on a simulator: after refusal both screens stay usable and show "Microphone permission denied".

## Status on 2026-10-31

The owner asked to release, so the fixes below are applied. Where an item above names an effect by its old title, this table gives the new one.

| Item | Status | What changed |
| --- | --- | --- |
| 1 Wallet | Fixed | Now "Metal Card": a single tap, no payment flow or system phrases, invented mark, app-styled sheet, no card stack. The glint shader is unchanged |
| 2 Home screens | Fixed | No app-icon grid remains. Glow Orb sits on a CC0 misty path photo and Wave Reveal carries that scene to a dusk photo |
| 3 Telegram screens | Fixed | Now "Message Dissolve" and "Hidden Text", with redrawn icons, an original wallpaper and an invented chat style |
| 4 Voice Delete | Fixed | Restyled, redrawn icons, four bundled images, no network |
| 5 iMessage Effects | Fixed | Now "Message Flourishes", with teal bubbles, a flat top bar and no call button. Encore is now rings rippling out of the bubble and Beams is now warm daylight shafts, so neither matches Echo or Lasers |
| 6 NameDrop | Fixed | Now "Wave Reveal", an animation from a misty morning scene to a dusk photo. No contact poster, no real person, no share choice |
| 7 Cracked Screen, Crackgate | Fixed | Abstract scene with an invented clock and a persistent caption. Crackgate is now "Hinge Crack" and the product name is gone |
| 8 Thanos | Fixed | Now "Dust" |
| 9 Weather | Fixed | New copy, labelled "Sample forecast", left-aligned layout, solid range bars, redrawn icons |
| 10 Orbs, Banners | Fixed | "Glow Orb" is a centred gold and jade orb with a soft halo and no screen-edge glow, "Morphing thinking blob", invented app name in the banner, new Banners line |
| 11 Cards | Fixed | Invented issuers, obviously fake numbers, contactless mark removed |
| 12 Trademarked titles | Fixed | "Instant Camera" with a neutral stripe, "Mystic Ball" with a 7, "The Eye" with new copy |
| 13 Positioning | Fixed in the catalog | Beer Foam (Foam lab), Linear Gradient, Circular Gradient and Scroll Reactive removed. A reviewer may still call the app a tech demo |
| 14 App name | Open | Unchanged: "Effects" |
| 15, 16 Lighter, Beer | Open | Age rating answers, and keep Beer out of screenshots |
| 17 Scratch-off | Fixed | Now "Lucky Clover" in the UI, with symbols only: no points, bonus strip or ticket price. The simulated gambling answer can be None |
| 18 Jokes and names | Fixed | Invented people, everyday chat scripts, developer in-jokes removed |
| 19 Device frames | Open | Nothing changed. Applies to marketing images |
| 20 Flashlight | Fixed | New copy. The SF Symbol PNGs are deleted and the screen uses plain sliders and a switch |
| 21 Permissions | No change needed | Already verified |

## Fixed in the repository (Applied)

| Risk | Change |
Expand All @@ -122,6 +149,6 @@ Dandelion and Birthday Candle ask for the microphone as soon as they open. Apple

## Other decisions

- **Portrait lock:** `app.json` now sets portrait, since tilt effects would otherwise rotate the layout mid-gesture. It does change Crackgate: rotating a phone no longer replays it (a tap still does), and the unfolded landscape layout on iPhone Duo was never tested. Check it on a Duo, or remove `orientation` if that effect matters more.
- **FFmpeg:** set `"disableFFmpeg": true` on the react-native-audio-api plugin. The app decodes no audio files, so this should remove LGPL libraries, OpenSSL and about 6.5 MB. It needs `pod install`, so it was not applied or tested.
- **Barcode scanning:** set `"barcodeScannerEnabled": false` on expo-camera. It removes ZXingObjC, which the app never uses. Also needs `pod install`.
- **Portrait lock:** `app.json` now sets portrait, since tilt effects would otherwise rotate the layout mid-gesture. Hinge Crack replays on a tap. Rotating no longer replays it.
- **FFmpeg:** `"disableFFmpeg": true` is set on the react-native-audio-api plugin. The Release build on 2026-10-31 has no FFmpeg frameworks.
- **Barcode scanning:** `"barcodeScannerEnabled": false` is set on expo-camera. See `docs/credits.md`.
Loading
Loading