Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
e9ac4f4
chore: scaffold eleven new effect screens
blazejkustra Oct 29, 2026
2eec60d
feat: add cracked screen example
blazejkustra Oct 29, 2026
3d654a4
feat: add iPhone Duo crackgate example
blazejkustra Oct 29, 2026
e24b1cc
feat: add polaroid example
blazejkustra Oct 29, 2026
2ca29cc
feat: add scratch-off example
blazejkustra Oct 29, 2026
f90c8d4
feat: add Apple Pay wallet example
blazejkustra Oct 29, 2026
a3a659c
feat: add CRT power off example
blazejkustra Oct 29, 2026
9965a44
feat: add Dynamic Island flashlight example
blazejkustra Oct 29, 2026
12711dc
feat: add NameDrop example
blazejkustra Oct 29, 2026
ae8828b
feat: add bubble wrap example
blazejkustra Oct 29, 2026
c8c352b
feat: add magnet-driven ferrofluid example
blazejkustra Oct 29, 2026
b12fd04
feat: add lava lamp example
blazejkustra Oct 29, 2026
4f57622
refactor: drop the back buttons from the X effects
blazejkustra Oct 30, 2026
da2bc4a
feat: make the crackgate failure play on its own
blazejkustra Oct 30, 2026
d9b332a
feat: show a real iOS home screen inside the CRT
blazejkustra Oct 30, 2026
60dbf9c
fix: continue the lava lamp glass into the base
blazejkustra Oct 30, 2026
6f7b2f5
feat: rebuild NameDrop to match the iOS animation
blazejkustra Oct 30, 2026
73b81ad
feat: animate the cracked screen impact
blazejkustra Oct 30, 2026
c17b085
fix: round the wallet card in its shader
blazejkustra Oct 30, 2026
9546981
feat: show the real app inside the CRT
blazejkustra Oct 30, 2026
fbdabbf
fix: keep the CRT power state in sync with the splash
blazejkustra Oct 30, 2026
03fa5de
feat: stack polaroid prints and shoot them with the real camera
blazejkustra Oct 30, 2026
b869027
fix: smooth the NameDrop card and colour the glow
blazejkustra Oct 30, 2026
976867c
fix: keep the app running on builds without expo-camera
blazejkustra Oct 30, 2026
c90b15c
fix: replace the polaroid whirr with a softer shutter sound
blazejkustra Oct 30, 2026
3897ef2
fix: soften the NameDrop glow
blazejkustra Oct 30, 2026
db243f4
chore: prepare the example app for App Store submission
blazejkustra Oct 30, 2026
dcdafb5
feat: rebuild the home screen as an effect catalog
blazejkustra Oct 30, 2026
25cceeb
refactor: remove back buttons and tutorial overlays from effect screens
blazejkustra Oct 30, 2026
eb6623e
fix: start worklets bundle mode in release builds
blazejkustra Oct 30, 2026
02e97a5
docs: update the asset audit for the catalog thumbnails
blazejkustra Oct 30, 2026
fbfba7c
fix: refresh catalog previews and clean effect screen copy
blazejkustra Oct 30, 2026
d109038
docs: list the portrait lock as an owner decision
blazejkustra Oct 30, 2026
efb8b26
feat: remove the cigarette effect
blazejkustra Oct 30, 2026
c1295cd
fix: correct the table photo credit and pin the wordmark size
blazejkustra Oct 30, 2026
141eb1c
feat: rename the app to Effects with a ferrofluid icon
blazejkustra Oct 30, 2026
fc272ea
Merge main into feat/catalog-redesign
blazejkustra Oct 30, 2026
85d9f0a
feat: ship dark mode, a config splash and the Expo 58 app config
blazejkustra Oct 30, 2026
5b7be9d
fix: keep the back swipe working on Sauron Eye
blazejkustra Oct 30, 2026
3e0caef
fix: retake the Beer Foam tile with the current labels
blazejkustra Oct 30, 2026
fb84db2
feat: use SF Symbols and Liquid Glass in the home top bar
blazejkustra Oct 30, 2026
8b32ac8
docs: record the real App Store release state
blazejkustra Oct 30, 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
43 changes: 43 additions & 0 deletions docs/app-store/CHECKLIST.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Submission checklist

In order. Steps marked Done are finished. The rest need the owner, and steps 1 to 4 stop a submission today.

## Before anything else

1. Decide the fixes in `review-risks.md`. Items 1 to 8 are likely rejections. Keep or rework each effect, then apply the changes.
2. Replace or clear every blocker in `asset-audit.md`.
3. Decide `disableFFmpeg` and `barcodeScannerEnabled` as described in `review-risks.md`. Both are still unset. Either change needs `yarn example prebuild:clean`, a pod install and a new archive. Done on `feat/catalog-redesign`: `main` is merged (Expo 58, React Native 0.88.1, react-native-webgpu 0.17, react-native-audio-api 0.13), the polyfill stays, and all iOS config lives in `app.json`.
4. Merge to `main`, so that `docs/privacy-policy.md` and `docs/credits.md` are live at their GitHub URLs. Both return 404 today, so the About links fail until the merge. Open both links in a private window. To use a proper domain or GitHub Pages instead, update the URL in `AboutScreen.tsx` and in `metadata.md`.
5. Done: the About screen links `docs/credits.md`.

## Confirm

6. Confirm publishing kustrablazej@gmail.com in the privacy policy and the review notes, or swap in a dedicated address.
7. Have someone qualified read the privacy policy and the licence notes. They are written from the code, and they are not legal advice.
8. Confirm the bundle ID `com.blazejkustra.rneffects` and the display name "Effects". The bundle ID cannot change after the first upload.
9. Check the app icon. The generated AppIcon set holds the 1024 px Ferrofluid capture with no alpha channel. Confirm you like it on a real home screen.

## Apple Developer account

10. Check that the Apple Developer Program membership for team 9S2Q77K6U6 is active and that the Paid Apps and Free Apps agreements are accepted. For an individual account, your legal name appears as the seller.
11. EU only: complete the Digital Services Act trader status in App Store Connect, or the app will not be listed in the EU. Trader status publishes your address and phone number, so decide before release.
12. Done: automatic signing registered the App ID and created an App Store profile that expires on 2027-10-30. Signing uses a cloud-managed Apple Distribution certificate, so the Mac keychain has no local Distribution identity. Exports need a working Xcode account session.

## App Store Connect

13. Create the app record with the values in `metadata.md`.
14. Fill in Pricing and Availability (free, regions), the App Privacy answers, the age rating answers and the review notes.
15. Set Content Rights to "contains third-party content" with rights to use it. Answer only after step 2.

## Screenshots

16. Capture on a real iPhone or simulator, with no dev tooling or status overlays, at 6.9-inch (1320 x 2868) or the size App Store Connect currently asks for. Use up to ten images.
17. Show interactive, original effects: Dandelion, Ferrofluid, Lava Lamp, Hourglass, Bubble Wrap. Leave out anything with another company's look, plus Beer. An app preview video is optional.

## Build and upload

18. In `app.json`, keep `version` 1.0.0 and `ios.buildNumber` 1. Raise `buildNumber` for each upload, and raise `version` after each release.
19. Done: the generated project is `example/ios/Effects`, `AppDelegate.swift` has no hardcoded Metro host, and `HERMES_CLI_PATH` resolves inside the worktree. The built bundle is Hermes bytecode 99. The IPA has the expected Info.plist keys, iPhone only, no background modes, and the dark interface style.
20. A signed App Store build exists at `example/ios/build/export/Effects.ipa`, from `example/ios/build/Effects.xcarchive` (Xcode 27.2, build 27B52, iOS 27.2 SDK). It has not been validated by Apple: this Mac has no altool credentials, and step 13 has to come first. Open the archive in Xcode Organizer, run Validate App, then Distribute App to App Store Connect. The `ios/build` folder is git-ignored, and `prebuild --clean` deletes it, so archive again after any clean prebuild.
21. Debug builds hide Release-only failures in this app, so never rely on them. Every route passed in a Release build on an iOS 26.5 simulator, including microphone, camera and motion refusal. Still to do on a real iPhone: first launch, all effects, real microphone, camera and sensors, Liquid Glass in the top bar, airplane mode, and the About links after step 4. A development-signed copy of the archive is installed on the iPhone 16.
22. Select the build, then Add for Review, and submit. Choose manual release if you want control of the launch date.
40 changes: 40 additions & 0 deletions docs/app-store/asset-audit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Asset provenance audit

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.

## 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.
- **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`.

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.
125 changes: 125 additions & 0 deletions docs/app-store/metadata.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# App Store metadata

Paste these into App Store Connect. Limits are noted where Apple enforces them. Items marked DECISION depend on the owner's choices in `review-risks.md`.

## Identity

| Field | Value |
| --- | --- |
| App name (30) | Effects |
| Subtitle (30) | Shaders 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 |

"Effects" is the store name and matches the name under the icon. Check availability in App Store Connect before the first upload; if it is taken, use a subtitle-style fallback such as "Effects: Shader Toys". "React Native Effects" carries a trademark risk (see `review-risks.md`).

## URLs

| Field | Value |
| --- | --- |
| Privacy Policy URL | https://github.com/blazejkustra/react-native-effects/blob/main/docs/privacy-policy.md |
| Support URL | https://github.com/blazejkustra/react-native-effects/issues |
| Marketing URL (optional) | https://github.com/blazejkustra/react-native-effects |

The privacy URL resolves only after `docs/privacy-policy.md` reaches `main`. The About screen links to the same URL.

## Promotional text (170)

Dozens of live GPU effects you can touch. Crack the glass, blow out a candle, pour a drink, stir a lava lamp. Every frame renders in real time on your iPhone.

## Description (DECISION: keep every named effect in sync with the final catalog)

Effects is a pocket collection of interactive visual effects. Every one is a real-time shader running on your iPhone's GPU, and every one responds to you: touch, tilt, sound and motion.

Things to try:

- Tap hard 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
- Shake an instant print while it develops
- Scratch foil, pop bubble wrap, flip an hourglass

There are also fabrics, liquid metal, northern lights, fire, ink and weather skies to play with, plus chat animations that turn messages to dust.

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.

## Keywords (100)

shader,gpu,visual,interactive,physics,particles,webgpu,generative,satisfying,fidget,art,animation

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

## Age rating questionnaire

Apple's current questionnaire. Answers reflect the catalog as of 2026-10-30.

| Question | Answer | Reason |
| --- | --- | --- |
| Parental controls | No | |
| Age assurance | No | |
| Unrestricted web access | No | About links open in the system browser |
| User-generated content | No | Camera prints stay on device and are never shared |
| Messaging and chat | No | Chat screens are scripted animations |
| Advertising | No | |
| Social media or social feed | No | |
| Profanity or crude humor | None | |
| Horror or fear themes | None | |
| Alcohol, tobacco, or drug use or references | Infrequent | Beer and Lighter effects |
| Medical or treatment information | None | |
| Health or wellness topics | No | |
| Mature or suggestive themes | None | |
| Sexual content or nudity | None | |
| Cartoon or fantasy violence | None | |
| Realistic violence | None | |
| Guns or other weapons | None | |
| Gambling | No | No real money |
| Simulated gambling | Infrequent | Scratch-off card with dollar prizes |
| 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.

Do not tick "Made for Kids".

## App Privacy (nutrition label)

- Do you or your third-party partners collect data from this app? **No, data not collected.**
- Tracking: **No.**
- Resulting label: **Data Not Collected.**

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.

## 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.

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 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.

Contact: kustrablazej@gmail.com
Loading
Loading