├── .expo-shared
├── README.md
└── assets.json
├── .gitignore
├── .prettierignore
├── .solidarity
├── App.js
├── README.md
├── app.json
├── app
├── app.tsx
├── components
│ ├── auto-image
│ │ ├── auto-image.story.tsx
│ │ └── auto-image.tsx
│ ├── back-button
│ │ ├── back-button.story.tsx
│ │ └── back-button.tsx
│ ├── bullet-item
│ │ └── bullet-item.tsx
│ ├── button
│ │ ├── button.presets.ts
│ │ ├── button.props.ts
│ │ ├── button.story.tsx
│ │ └── button.tsx
│ ├── checkbox
│ │ ├── checkbox.props.ts
│ │ ├── checkbox.story.tsx
│ │ └── checkbox.tsx
│ ├── conduct
│ │ ├── conduct.story.tsx
│ │ └── conduct.tsx
│ ├── contact
│ │ ├── contact.story.tsx
│ │ └── contact.tsx
│ ├── content-link
│ │ ├── content-link.story.tsx
│ │ └── content-link.tsx
│ ├── footer
│ │ ├── footer.presets.ts
│ │ ├── footer.props.ts
│ │ ├── footer.story.tsx
│ │ ├── footer.tsx
│ │ └── index.ts
│ ├── form-row
│ │ ├── form-row.presets.ts
│ │ ├── form-row.props.tsx
│ │ ├── form-row.story.tsx
│ │ └── form-row.tsx
│ ├── gerding-theater
│ │ ├── gerding-theater.story.tsx
│ │ ├── gerding-theater.tsx
│ │ ├── img.venue.png
│ │ ├── img.venue@2x.png
│ │ └── img.venue@3x.png
│ ├── getting-to-chain-react
│ │ ├── animations
│ │ │ └── scooter-halloween.json
│ │ ├── getting-to-chain-react.story.tsx
│ │ ├── getting-to-chain-react.tsx
│ │ ├── logo-lyft@1x.png
│ │ ├── logo-lyft@2x.png
│ │ ├── logo-lyft@3x.png
│ │ ├── logo-uber@1x.png
│ │ ├── logo-uber@2x.png
│ │ └── logo-uber@3x.png
│ ├── gradient-background
│ │ ├── gradient-background.story.tsx
│ │ └── gradient-background.tsx
│ ├── header
│ │ ├── header.props.ts
│ │ ├── header.story.tsx
│ │ └── header.tsx
│ ├── icon
│ │ ├── icon.props.ts
│ │ ├── icon.story.tsx
│ │ ├── icon.tsx
│ │ └── icons
│ │ │ ├── arrow-left.png
│ │ │ ├── arrow-left@2x.png
│ │ │ ├── bullet.png
│ │ │ ├── bullet@2x.png
│ │ │ ├── index.ts
│ │ │ └── ladybug.png
│ ├── index.ts
│ ├── nearby-attractions
│ │ ├── attraction.tsx
│ │ ├── attractions-list.tsx
│ │ ├── attractions-map-callout.tsx
│ │ ├── attractions-map.tsx
│ │ ├── images
│ │ │ ├── Close.png
│ │ │ ├── Close@2x.png
│ │ │ ├── Close@3x.png
│ │ │ ├── star.filled.png
│ │ │ ├── star.filled@2x.png
│ │ │ ├── star.filled@3x.png
│ │ │ ├── star.unfilled.png
│ │ │ ├── star.unfilled@2x.png
│ │ │ └── star.unfilled@3x.png
│ │ ├── nearby-attractions.story.tsx
│ │ ├── nearby-attractions.tsx
│ │ ├── rating.tsx
│ │ └── render-link.tsx
│ ├── presented-by
│ │ ├── images
│ │ │ ├── bg.team.png
│ │ │ ├── bg.team@2x.png
│ │ │ ├── bg.team@3x.png
│ │ │ ├── logo.infinitered.png
│ │ │ ├── logo.infinitered@2x.png
│ │ │ └── logo.infinitered@3x.png
│ │ ├── presented-by.presets.ts
│ │ ├── presented-by.story.tsx
│ │ └── presented-by.tsx
│ ├── schedule-cell
│ │ ├── images
│ │ │ ├── afterparty-G2i.png
│ │ │ ├── coffee-small.png
│ │ │ ├── lunch.png
│ │ │ ├── panelist.png
│ │ │ ├── registration.png
│ │ │ └── sponsor-bumped.png
│ │ ├── render-image.tsx
│ │ ├── render-time.tsx
│ │ ├── schedule-cell.presets.ts
│ │ ├── schedule-cell.props.ts
│ │ ├── schedule-cell.story.tsx
│ │ └── schedule-cell.tsx
│ ├── schedule-nav
│ │ ├── schedule-nav.story.tsx
│ │ └── schedule-nav.tsx
│ ├── screen
│ │ ├── screen.presets.ts
│ │ ├── screen.props.ts
│ │ └── screen.tsx
│ ├── social-button
│ │ ├── social-button.presets.ts
│ │ ├── social-button.props.ts
│ │ ├── social-button.story.tsx
│ │ ├── social-button.tsx
│ │ └── social_icon_assets
│ │ │ ├── dribbble.png
│ │ │ ├── dribbble@2x.png
│ │ │ ├── dribbble@3x.png
│ │ │ ├── email.icon.png
│ │ │ ├── email.icon@2x.png
│ │ │ ├── email.icon@3x.png
│ │ │ ├── facebook.png
│ │ │ ├── facebook@2x.png
│ │ │ ├── facebook@3x.png
│ │ │ ├── github.png
│ │ │ ├── github@2x.png
│ │ │ ├── github@3x.png
│ │ │ ├── instagram.png
│ │ │ ├── instagram@2x.png
│ │ │ ├── instagram@3x.png
│ │ │ ├── link.png
│ │ │ ├── link@2x.png
│ │ │ ├── link@3x.png
│ │ │ ├── medium.png
│ │ │ ├── medium@2x.png
│ │ │ ├── medium@3x.png
│ │ │ ├── phone.icon.png
│ │ │ ├── phone.icon@2x.png
│ │ │ ├── phone.icon@3x.png
│ │ │ ├── slack.png
│ │ │ ├── slack@2x.png
│ │ │ ├── slack@3x.png
│ │ │ ├── twitter.png
│ │ │ ├── twitter@2x.png
│ │ │ └── twitter@3x.png
│ ├── speaker-bio
│ │ └── speaker-bio.tsx
│ ├── speaker-image
│ │ ├── img.speaker.lg.png
│ │ ├── img.speaker.lg@2x.png
│ │ ├── img.speaker.lg@3x.png
│ │ └── speaker-image.tsx
│ ├── sponsors
│ │ ├── logos
│ │ │ ├── Additional_AWS_AA_AfterParty.png
│ │ │ ├── Additional_AWS_AA_AfterParty@2x.png
│ │ │ ├── Additional_AWS_AA_AfterParty@3x.png
│ │ │ ├── Additional_DevLifts_Streches.png
│ │ │ ├── Additional_DevLifts_Streches@2x.png
│ │ │ ├── Additional_DevLifts_Streches@3x.png
│ │ │ ├── Additional_G2i.png
│ │ │ ├── Additional_G2i@2x.png
│ │ │ ├── Additional_G2i@3x.png
│ │ │ ├── Additional_Playstation_Wifi.png
│ │ │ ├── Additional_Playstation_Wifi@2x.png
│ │ │ ├── Additional_Playstation_Wifi@3x.png
│ │ │ ├── Additional_SquarespaceBadges.png
│ │ │ ├── Additional_SquarespaceBadges@2x.png
│ │ │ ├── Additional_SquarespaceBadges@3x.png
│ │ │ ├── Additional_bumped-alt.png
│ │ │ ├── Additional_bumped-alt@2x.png
│ │ │ ├── Additional_bumped-alt@3x.png
│ │ │ ├── Bronze_Airship.png
│ │ │ ├── Bronze_Airship@2x.png
│ │ │ ├── Bronze_Airship@3x.png
│ │ │ ├── Bronze_BuilderX.png
│ │ │ ├── Bronze_BuilderX@2x.png
│ │ │ ├── Bronze_BuilderX@3x.png
│ │ │ ├── Bronze_Cambia.png
│ │ │ ├── Bronze_Cambia@2x.png
│ │ │ ├── Bronze_Cambia@3x.png
│ │ │ ├── Bronze_Echobind.png
│ │ │ ├── Bronze_Echobind@2x.png
│ │ │ ├── Bronze_Echobind@3x.png
│ │ │ ├── Bronze_Facebook.png
│ │ │ ├── Bronze_Facebook@2x.png
│ │ │ ├── Bronze_Facebook@3x.png
│ │ │ ├── Bronze_G2i.png
│ │ │ ├── Bronze_G2i@2x.png
│ │ │ ├── Bronze_G2i@3x.png
│ │ │ ├── Bronze_Modus.png
│ │ │ ├── Bronze_Modus@2x.png
│ │ │ ├── Bronze_Modus@3x.png
│ │ │ ├── Gold_Callstack.png
│ │ │ ├── Gold_Callstack@2x.png
│ │ │ ├── Gold_Callstack@3x.png
│ │ │ ├── Gold_Coinbase.png
│ │ │ ├── Gold_Coinbase@2x.png
│ │ │ ├── Gold_Coinbase@3x.png
│ │ │ ├── Gold_Sentry.png
│ │ │ ├── Gold_Sentry@2x.png
│ │ │ ├── Gold_Sentry@3x.png
│ │ │ ├── Platinum_AWS.png
│ │ │ ├── Platinum_AWS@2x.png
│ │ │ ├── Platinum_AWS@3x.png
│ │ │ ├── Platinum_Amazon_Alexa.png
│ │ │ ├── Platinum_Amazon_Alexa@2x.png
│ │ │ ├── Platinum_Amazon_Alexa@3x.png
│ │ │ ├── Silver_AmazonWebService.png
│ │ │ ├── Silver_AmazonWebService@2x.png
│ │ │ ├── Silver_AmazonWebService@3x.png
│ │ │ ├── Silver_Bugsnag.png
│ │ │ ├── Silver_Bugsnag@2x.png
│ │ │ ├── Silver_Bugsnag@3x.png
│ │ │ ├── Silver_GoDaddy.png
│ │ │ ├── Silver_GoDaddy@2x.png
│ │ │ ├── Silver_GoDaddy@3x.png
│ │ │ ├── Silver_ServerlessGuru.png
│ │ │ ├── Silver_ServerlessGuru@2x.png
│ │ │ ├── Silver_ServerlessGuru@3x.png
│ │ │ ├── playstation.png
│ │ │ ├── playstation@2x.png
│ │ │ └── playstation@3x.png
│ │ ├── sponsor-logo.presets.ts
│ │ ├── sponsor-logo.tsx
│ │ ├── sponsors.story.tsx
│ │ └── sponsors.tsx
│ ├── survey-link
│ │ ├── survey-link.story.tsx
│ │ └── survey-link.tsx
│ ├── switch
│ │ ├── switch.props.ts
│ │ ├── switch.story.tsx
│ │ └── switch.tsx
│ ├── tab-icon
│ │ ├── icons
│ │ │ ├── calendar.active.png
│ │ │ ├── calendar.active@2x.png
│ │ │ ├── calendar.active@3x.png
│ │ │ ├── calendar.inactive.png
│ │ │ ├── calendar.inactive@2x.png
│ │ │ ├── calendar.inactive@3x.png
│ │ │ ├── info.active.png
│ │ │ ├── info.active@2x.png
│ │ │ ├── info.active@3x.png
│ │ │ ├── info.inactive.png
│ │ │ ├── info.inactive@2x.png
│ │ │ ├── info.inactive@3x.png
│ │ │ ├── map.active.png
│ │ │ ├── map.active@2x.png
│ │ │ ├── map.active@3x.png
│ │ │ ├── map.inactive.png
│ │ │ ├── map.inactive@2x.png
│ │ │ ├── map.inactive@3x.png
│ │ │ ├── profile.active.png
│ │ │ ├── profile.active@2x.png
│ │ │ ├── profile.active@3x.png
│ │ │ ├── profile.inactive.png
│ │ │ ├── profile.inactive@2x.png
│ │ │ └── profile.inactive@3x.png
│ │ ├── tab-icon.story.tsx
│ │ └── tab-icon.tsx
│ ├── talk-title
│ │ └── talk-title.tsx
│ ├── text-field
│ │ ├── text-field.story.tsx
│ │ └── text-field.tsx
│ ├── text
│ │ ├── text.presets.ts
│ │ ├── text.props.ts
│ │ ├── text.story.tsx
│ │ └── text.tsx
│ ├── title-bar
│ │ ├── icon.back-arrow.png
│ │ ├── icon.back-arrow@2x.png
│ │ ├── icon.back-arrow@3x.png
│ │ ├── title-bar.story.tsx
│ │ └── title-bar.tsx
│ ├── travel-option
│ │ ├── Car.png
│ │ ├── Car@2x.png
│ │ ├── Car@3x.png
│ │ ├── Lightrail.png
│ │ ├── Lightrail@2x.png
│ │ ├── Lightrail@3x.png
│ │ ├── travel-option.presets.ts
│ │ ├── travel-option.props.ts
│ │ ├── travel-option.story.tsx
│ │ └── travel-option.tsx
│ ├── wallpaper
│ │ ├── bg.png
│ │ ├── bg@2x.png
│ │ ├── wallpaper.presets.ts
│ │ ├── wallpaper.props.ts
│ │ ├── wallpaper.story.tsx
│ │ └── wallpaper.tsx
│ └── wi-fi
│ │ ├── wi-fi.story.tsx
│ │ └── wi-fi.tsx
├── config
│ └── env.js
├── i18n
│ ├── en.json
│ ├── i18n.ts
│ ├── index.ts
│ └── translate.ts
├── models
│ ├── environment.ts
│ ├── event-store
│ │ ├── event-store.test.ts
│ │ └── event-store.ts
│ ├── event
│ │ └── event.ts
│ ├── extensions
│ │ ├── with-environment.ts
│ │ └── with-root-store.ts
│ ├── index.ts
│ ├── root-store
│ │ ├── root-store-context.ts
│ │ ├── root-store.ts
│ │ └── setup-root-store.ts
│ ├── setting
│ │ ├── setting.test.ts
│ │ └── setting.ts
│ └── speaker
│ │ ├── speaker.test.ts
│ │ └── speaker.ts
├── navigators
│ ├── app-navigator.tsx
│ ├── index.ts
│ └── navigation-utilities.tsx
├── screens
│ ├── code-of-conduct
│ │ └── code-of-conduct-screen.tsx
│ ├── error
│ │ ├── error-boundary.tsx
│ │ └── error-component.tsx
│ ├── event-details
│ │ ├── event-details-screen.tsx
│ │ ├── image-dimension-helpers.ts
│ │ ├── images
│ │ │ ├── bumped.png
│ │ │ ├── img.afterparty-g2i.png
│ │ │ ├── img.afterparty-squarespace.png
│ │ │ ├── img.break.png
│ │ │ ├── img.event.png
│ │ │ ├── img.event@2x.png
│ │ │ ├── img.event@3x.png
│ │ │ ├── img.partylogo.png
│ │ │ ├── img.partylogo@2x.png
│ │ │ ├── img.partylogo@3x.png
│ │ │ ├── sponsor-bumped-thumb.png
│ │ │ └── sponsor-bumped.png
│ │ ├── render-after-party.tsx
│ │ ├── render-announcement.tsx
│ │ ├── render-break.tsx
│ │ ├── render-default-event.tsx
│ │ ├── render-event-type.tsx
│ │ ├── render-meal.tsx
│ │ ├── render-panel.tsx
│ │ ├── render-talk.tsx
│ │ └── render-workshop.tsx
│ ├── index.ts
│ ├── info
│ │ └── info-screen.tsx
│ ├── schedule
│ │ ├── render-event.tsx
│ │ ├── schedule-content.tsx
│ │ ├── schedule-screen.tsx
│ │ └── schedule-workshops.tsx
│ ├── venue
│ │ ├── animations
│ │ │ └── sunset.json
│ │ └── venue-screen.tsx
│ └── welcome
│ │ ├── bg.welcome.png
│ │ ├── bg.welcome@2x.png
│ │ ├── bg.welcome@3x.png
│ │ └── welcome-screen.tsx
├── services
│ ├── api
│ │ ├── api-config.ts
│ │ ├── api-problem.test.ts
│ │ ├── api-problem.ts
│ │ ├── api.ts
│ │ ├── api.types.ts
│ │ ├── character-api.ts
│ │ └── index.ts
│ └── reactotron
│ │ ├── index.ts
│ │ ├── reactotron-config.ts
│ │ ├── reactotron.ts
│ │ ├── tron.ts
│ │ └── tron.web.ts
├── theme
│ ├── color.ts
│ ├── fonts
│ │ └── index.ts
│ ├── index.ts
│ ├── palette.ts
│ ├── spacing.ts
│ ├── timing.ts
│ └── typography.ts
└── utils
│ ├── delay.ts
│ ├── ignore-warnings.ts
│ ├── info.ts
│ ├── keychain.ts
│ ├── storage
│ ├── index.ts
│ ├── storage.test.ts
│ └── storage.ts
│ └── validate.ts
├── assets
├── data
│ └── event-data.json
├── fonts
│ └── custom-fonts.md
└── images
│ ├── adaptive-icon.png
│ ├── favicon.png
│ ├── icon-default.png
│ ├── icon-ios.png
│ ├── icon.png
│ ├── splash-tablet-landscape.png
│ ├── splash-tablet-portrait.png
│ └── splash.png
├── babel.config.js
├── bin
├── downloadExpoApp.sh
├── postInstall
└── setup
├── e2e
├── README.md
├── config.json
├── firstTest.spec.js
├── init.js
└── reload.js
├── eas.json
├── ignite
└── templates
│ ├── component
│ ├── NAME.story.tsx.ejs
│ └── NAME.tsx.ejs
│ ├── model
│ ├── NAME.test.ts.ejs
│ └── NAME.ts.ejs
│ ├── navigator
│ └── NAME-navigator.tsx.ejs
│ └── screen
│ └── NAME-screen.tsx.ejs
├── package.json
├── react-native.config.js
├── storybook
├── index.ts
├── storybook-registry.ts
├── storybook.tsx
├── toggle-storybook.tsx
├── toggle-storybook.web.tsx
└── views
│ ├── index.ts
│ ├── story-screen.tsx
│ ├── story.tsx
│ └── use-case.tsx
├── test
├── __snapshots__
│ └── storyshots.test.ts.snap
├── i18n.test.ts
├── mock-async-storage.ts
├── mock-file.ts
├── mock-i18n.ts
├── mock-react-native-image.ts
├── mock-reactotron.ts
├── setup.ts
└── storyshots.test.ts
├── tsconfig.json
├── webpack.config.js
└── yarn.lock
/.expo-shared/README.md:
--------------------------------------------------------------------------------
1 | > Why do I have a folder named ".expo-shared" in my project?
2 |
3 | The ".expo-shared" folder is created when running commands that produce state that is intended to be shared with all developers on the project. For example, "npx expo-optimize".
4 |
5 | > What does the "assets.json" file contain?
6 |
7 | The "assets.json" file describes the assets that have been optimized through "expo-optimize" and do not need to be processed again.
8 |
9 | > Should I commit the ".expo-shared" folder?
10 |
11 | Yes, you should share the ".expo-shared" folder with your collaborators.
12 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # Xcode
6 | #
7 | build/
8 | *.pbxuser
9 | !default.pbxuser
10 | *.mode1v3
11 | !default.mode1v3
12 | *.mode2v3
13 | !default.mode2v3
14 | *.perspectivev3
15 | !default.perspectivev3
16 | xcuserdata
17 | *.xccheckout
18 | *.moved-aside
19 | DerivedData
20 | *.hmap
21 | *.ipa
22 | *.xcuserstate
23 |
24 | # Android/IntelliJ
25 | #
26 | build/
27 | .idea
28 | .gradle
29 | local.properties
30 | *.iml
31 |
32 | # node.js
33 | #
34 | node_modules/
35 | npm-debug.log
36 | yarn-error.log
37 |
38 | # BUCK
39 | buck-out/
40 | \.buckd/
41 | *.keystore
42 | !debug.keystore
43 |
44 | # fastlane
45 | #
46 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
47 | # screenshots whenever they are needed.
48 | # For more information about the recommended setup visit:
49 | # https://docs.fastlane.tools/best-practices/source-control/
50 |
51 | */fastlane/report.xml
52 | */fastlane/Preview.html
53 | */fastlane/screenshots
54 |
55 | # Bundle artifact
56 | *.jsbundle
57 |
58 | # CocoaPods
59 | /ios/Pods/
60 |
61 | # Ignite-specific items below
62 | # You can safely replace everything above this comment with whatever is
63 | # in the default .gitignore generated by React-Native CLI
64 |
65 | # VS Code
66 | .vscode
67 |
68 | # Expo
69 | .expo/*
70 | bin/Exponent.app
71 |
72 | npm-debug.*
73 | *.jks
74 | *.p8
75 | *.p12
76 | *.key
77 | *.mobileprovision
78 | *.orig.*
79 | web-build/
80 |
81 | # Configurations
82 | app/config/env.*.js
83 | !env.js
84 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | ios
3 | android
4 | .vscode
5 | ignite/ignite.json
6 | package.json
7 |
--------------------------------------------------------------------------------
/.solidarity:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json.schemastore.org/solidaritySchema",
3 | "requirements": {
4 | "Node": [{ "rule": "cli", "binary": "node", "semver": ">=8.6.0" }],
5 | "Xcode": [
6 | {
7 | "rule": "cli",
8 | "binary": "xcodebuild",
9 | "version": "-version",
10 | "semver": ">=9.2.0",
11 | "platform": "darwin"
12 | }
13 | ],
14 | "CocoaPods": [
15 | {
16 | "rule": "cli",
17 | "binary": "pod",
18 | "version": "--version",
19 | "semver": ">=1.7.0",
20 | "platform": "darwin"
21 | }
22 | ]
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/App.js:
--------------------------------------------------------------------------------
1 | // This is the first file that ReactNative will run when it starts up.
2 | import App from "./app/app.tsx"
3 | import { registerRootComponent } from "expo"
4 |
5 | registerRootComponent(App)
6 | export default App
7 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "expo": {
3 | "name": "ChainReactApp2022",
4 | "slug": "ChainReactApp2022",
5 | "owner": "infinitered",
6 | "version": "2022.0.1",
7 | "orientation": "portrait",
8 | "backgroundColor": "#171539",
9 | "splash": {
10 | "image": "./assets/images/splash.png",
11 | "resizeMode": "contain",
12 | "backgroundColor": "#171539"
13 | },
14 | "updates": {
15 | "fallbackToCacheTimeout": 0
16 | },
17 | "assetBundlePatterns": ["**/*"],
18 | "android": {
19 | "icon": "./assets/images/icon.png",
20 | "adaptiveIcon": {
21 | "foregroundImage": "./assets/images/adaptive-icon.png",
22 | "backgroundColor": "#ffffff"
23 | },
24 | "package": "com.chainreactapp"
25 | },
26 | "ios": {
27 | "supportsTablet": true,
28 | "icon": "./assets/images/icon-ios.png",
29 | "splash": {
30 | "tabletImage": "./assets/images/splash-tablet-portrait.png"
31 | },
32 | "bundleIdentifier": "infinitered.stage.ChainReactConf"
33 | },
34 | "web": {
35 | "favicon": "./assets/images/favicon.png"
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/app/components/auto-image/auto-image.story.tsx:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | import React from "react"
3 | import { storiesOf } from "@storybook/react-native"
4 | import { StoryScreen, Story, UseCase } from "../../../storybook/views"
5 | import { AutoImage } from "./auto-image"
6 |
7 | declare let module
8 |
9 | const welcomeBG = require("../../screens/welcome/bg.welcome.png")
10 | const morty = { uri: "https://rickandmortyapi.com/api/character/avatar/2.jpeg" }
11 |
12 | storiesOf("AutoImage", module)
13 | .addDecorator((fn) => {fn()})
14 | .add("Style Presets", () => (
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | ))
32 |
--------------------------------------------------------------------------------
/app/components/auto-image/auto-image.tsx:
--------------------------------------------------------------------------------
1 | import React, { useLayoutEffect, useState } from "react"
2 | import {
3 | Image as RNImage,
4 | ImageProps as DefaultImageProps,
5 | ImageURISource,
6 | Platform,
7 | } from "react-native"
8 |
9 | type ImageProps = DefaultImageProps & {
10 | source: ImageURISource
11 | }
12 |
13 | /**
14 | * An Image wrapper component that autosizes itself to the size of the actual image.
15 | * You can always override by passing a width and height in the style.
16 | * If passing only one of width/height this image component will use the actual
17 | * size of the other dimension.
18 | *
19 | * This component isn't required, but is provided as a convenience so that
20 | * we don't have to remember to explicitly set image sizes on every image instance.
21 | *
22 | * To use as a stand-in replacement import { AutoImage as Image } and remove the
23 | * Image import from react-native. Now all images in that file are handled by this
24 | * component and are web-ready if not explicitly sized in the style property.
25 | */
26 | export function AutoImage(props: ImageProps) {
27 | const [imageSize, setImageSize] = useState({ width: 0, height: 0 })
28 |
29 | useLayoutEffect(() => {
30 | if (props.source?.uri) {
31 | RNImage.getSize(props.source.uri as any, (width, height) => {
32 | setImageSize({ width, height })
33 | })
34 | } else if (Platform.OS === "web") {
35 | // web requires a different method to get it's size
36 | RNImage.getSize(props.source as any, (width, height) => {
37 | setImageSize({ width, height })
38 | })
39 | } else {
40 | const { width, height } = RNImage.resolveAssetSource(props.source)
41 | setImageSize({ width, height })
42 | }
43 | }, [])
44 |
45 | return
46 | }
47 |
--------------------------------------------------------------------------------
/app/components/back-button/back-button.story.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { storiesOf } from "@storybook/react-native"
3 | import { StoryScreen, Story, UseCase } from "../../../storybook/views"
4 | import { BackButton } from "./back-button"
5 |
6 | storiesOf("BackButton", module)
7 | .addDecorator((fn) => {fn()})
8 | .add("Style Presets", () => (
9 |
10 |
11 |
12 |
13 |
14 | ))
15 |
--------------------------------------------------------------------------------
/app/components/back-button/back-button.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { Image, TextStyle, View, ViewStyle } from "react-native"
3 | import { HIT_SLOP, palette, spacing } from "../../theme"
4 | import { Text } from "../text/text"
5 |
6 | const HEADER_TEXT: TextStyle = {
7 | fontSize: 17,
8 | fontWeight: "600",
9 | lineHeight: 45,
10 | marginLeft: spacing.large,
11 | color: palette.shamrock,
12 | }
13 |
14 | const BACK_ARROW: ViewStyle = {
15 | flexDirection: "row",
16 | paddingLeft: spacing.large,
17 | alignItems: "center",
18 | justifyContent: "center",
19 | }
20 |
21 | export const BackButton = (props: { backTitle: string }) => {
22 | return (
23 |
24 |
25 |
26 |
27 | )
28 | }
29 |
--------------------------------------------------------------------------------
/app/components/bullet-item/bullet-item.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { View, ViewStyle, ImageStyle, TextStyle } from "react-native"
3 | import { Text } from "../text/text"
4 | import { Icon } from "../icon/icon"
5 | import { spacing, typography } from "../../theme"
6 |
7 | const BULLET_ITEM: ViewStyle = {
8 | flexDirection: "row",
9 | marginTop: spacing[4],
10 | paddingBottom: spacing[4],
11 | borderBottomWidth: 1,
12 | borderBottomColor: "#3A3048",
13 | }
14 | const BULLET_CONTAINER: ViewStyle = {
15 | marginRight: spacing[4] - 1,
16 | marginTop: spacing[2],
17 | }
18 | const BULLET: ImageStyle = {
19 | width: 8,
20 | height: 8,
21 | }
22 | const BULLET_TEXT: TextStyle = {
23 | flex: 1,
24 | fontFamily: typography.primary,
25 | color: "#BAB6C8",
26 | fontSize: 15,
27 | lineHeight: 22,
28 | }
29 |
30 | export interface BulletItemProps {
31 | text: string
32 | }
33 |
34 | export function BulletItem(props: BulletItemProps) {
35 | return (
36 |
37 |
38 |
39 |
40 | )
41 | }
42 |
--------------------------------------------------------------------------------
/app/components/button/button.presets.ts:
--------------------------------------------------------------------------------
1 | import { TextStyle, ViewStyle } from "react-native"
2 | import { color, palette, spacing } from "../../theme"
3 |
4 | /**
5 | * All text will start off looking like this.
6 | */
7 | const BASE_VIEW: ViewStyle = {
8 | paddingVertical: spacing.medium,
9 | paddingHorizontal: spacing.medium,
10 | borderRadius: 4,
11 | justifyContent: "center",
12 | alignItems: "center",
13 | }
14 |
15 | const DARK_BASE_VIEW: ViewStyle = {
16 | backgroundColor: color.palette.vintageRock,
17 | paddingVertical: spacing.small,
18 | }
19 |
20 | const BASE_TEXT: TextStyle = {
21 | paddingHorizontal: spacing.large,
22 | }
23 |
24 | /**
25 | * All the variations of text styling within the app.
26 | *
27 | * You want to customize these to whatever you need in your app.
28 | */
29 | export const viewPresets = {
30 | /**
31 | * A smaller piece of secondary information.
32 | */
33 | primary: { ...BASE_VIEW, backgroundColor: color.palette.crimson } as ViewStyle,
34 | dark: { ...BASE_VIEW, ...DARK_BASE_VIEW } as ViewStyle,
35 | link: {} as ViewStyle,
36 | }
37 |
38 | export const textPresets = {
39 | primary: { ...BASE_TEXT, fontSize: 9, color: color.palette.white } as TextStyle,
40 | dark: {
41 | color: color.palette.shamrock,
42 | fontSize: 14,
43 | textAlign: "center",
44 | } as TextStyle,
45 | link: { color: palette.shamrock } as TextStyle,
46 | }
47 |
48 | /**
49 | * A list of preset names.
50 | */
51 | export type ButtonPresetNames = keyof typeof viewPresets
52 |
--------------------------------------------------------------------------------
/app/components/button/button.props.ts:
--------------------------------------------------------------------------------
1 | import { StyleProp, TextStyle, TouchableOpacityProps, ViewStyle } from "react-native"
2 | import { ButtonPresetNames } from "./button.presets"
3 | import { TxKeyPath } from "../../i18n"
4 |
5 | export interface ButtonProps extends TouchableOpacityProps {
6 | /**
7 | * Text which is looked up via i18n.
8 | */
9 | tx?: TxKeyPath
10 |
11 | /**
12 | * The text to display if not using `tx` or nested components.
13 | */
14 | text?: string
15 |
16 | /**
17 | * An optional style override useful for padding & margin.
18 | */
19 | style?: StyleProp
20 |
21 | /**
22 | * An optional style override useful for the button text.
23 | */
24 | textStyle?: StyleProp
25 |
26 | /**
27 | * One of the different types of text presets.
28 | */
29 | preset?: ButtonPresetNames
30 |
31 | /**
32 | * One of the different types of text presets.
33 | */
34 | children?: React.ReactNode
35 | }
36 |
--------------------------------------------------------------------------------
/app/components/button/button.story.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { ViewStyle, TextStyle, Alert } from "react-native"
3 | import { storiesOf } from "@storybook/react-native"
4 | import { StoryScreen, Story, UseCase } from "../../../storybook/views"
5 | import { Button } from "./button"
6 |
7 | declare let module
8 |
9 | const buttonStyleArray: ViewStyle[] = [{ paddingVertical: 100 }, { borderRadius: 0 }]
10 |
11 | const buttonTextStyleArray: TextStyle[] = [{ fontSize: 20 }, { color: "#a511dc" }]
12 |
13 | storiesOf("Button", module)
14 | .addDecorator((fn) => {fn()})
15 | .add("Style Presets", () => (
16 |
17 |
18 |
20 |
21 |
23 |
24 |
32 |
33 | ))
34 |
--------------------------------------------------------------------------------
/app/components/button/button.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { TouchableOpacity } from "react-native"
3 | import { Text } from "../text/text"
4 | import { viewPresets, textPresets } from "./button.presets"
5 | import { ButtonProps } from "./button.props"
6 |
7 | /**
8 | * For your text displaying needs.
9 | *
10 | * This component is a HOC over the built-in React Native one.
11 | */
12 | export function Button(props: ButtonProps) {
13 | // grab the props
14 | const {
15 | preset = "primary",
16 | tx,
17 | text,
18 | style: styleOverride,
19 | textStyle: textStyleOverride,
20 | children,
21 | ...rest
22 | } = props
23 |
24 | const viewStyle = viewPresets[preset] || viewPresets.primary
25 | const viewStyles = [viewStyle, styleOverride]
26 | const textStyle = textPresets[preset] || textPresets.primary
27 | const textStyles = [textStyle, textStyleOverride]
28 |
29 | const content = children ||
30 |
31 | return (
32 |
33 | {content}
34 |
35 | )
36 | }
37 |
--------------------------------------------------------------------------------
/app/components/checkbox/checkbox.props.ts:
--------------------------------------------------------------------------------
1 | import { StyleProp, ViewStyle } from "react-native"
2 | import { TxKeyPath } from "../../i18n"
3 |
4 | export interface CheckboxProps {
5 | /**
6 | * Additional container style. Useful for margins.
7 | */
8 | style?: StyleProp
9 |
10 | /**
11 | * Additional outline style.
12 | */
13 | outlineStyle?: StyleProp
14 |
15 | /**
16 | * Additional fill style. Only visible when checked.
17 | */
18 | fillStyle?: StyleProp
19 |
20 | /**
21 | * Is the checkbox checked?
22 | */
23 | value?: boolean
24 |
25 | /**
26 | * The text to display if there isn't a tx.
27 | */
28 | text?: string
29 |
30 | /**
31 | * The i18n lookup key.
32 | */
33 | tx?: TxKeyPath
34 |
35 | /**
36 | * Multiline or clipped single line?
37 | */
38 | multiline?: boolean
39 |
40 | /**
41 | * Fires when the user tabs to change the value.
42 | */
43 | onToggle?: (newValue: boolean) => void
44 | }
45 |
--------------------------------------------------------------------------------
/app/components/checkbox/checkbox.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { TextStyle, TouchableOpacity, View, ViewStyle } from "react-native"
3 | import { Text } from "../text/text"
4 | import { color, spacing } from "../../theme"
5 | import { CheckboxProps } from "./checkbox.props"
6 |
7 | const ROOT: ViewStyle = {
8 | flexDirection: "row",
9 | paddingVertical: spacing[1],
10 | alignSelf: "flex-start",
11 | }
12 |
13 | const DIMENSIONS = { width: 16, height: 16 }
14 |
15 | const OUTLINE: ViewStyle = {
16 | ...DIMENSIONS,
17 | marginTop: 2, // finicky and will depend on font/line-height/baseline/weather
18 | justifyContent: "center",
19 | alignItems: "center",
20 | borderWidth: 1,
21 | borderColor: color.primaryDarker,
22 | borderRadius: 1,
23 | }
24 |
25 | const FILL: ViewStyle = {
26 | width: DIMENSIONS.width - 4,
27 | height: DIMENSIONS.height - 4,
28 | backgroundColor: color.primary,
29 | }
30 |
31 | const LABEL: TextStyle = { paddingLeft: spacing[2] }
32 |
33 | export function Checkbox(props: CheckboxProps) {
34 | const numberOfLines = props.multiline ? 0 : 1
35 |
36 | const rootStyle = [ROOT, props.style]
37 | const outlineStyle = [OUTLINE, props.outlineStyle]
38 | const fillStyle = [FILL, props.fillStyle]
39 |
40 | const onPress = props.onToggle ? () => props.onToggle && props.onToggle(!props.value) : null
41 |
42 | return (
43 |
49 | {props.value && }
50 |
51 |
52 | )
53 | }
54 |
--------------------------------------------------------------------------------
/app/components/conduct/conduct.story.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { storiesOf } from "@storybook/react-native"
3 | import { StoryScreen, Story, UseCase } from "../../../storybook/views"
4 | import { color } from "../../theme"
5 | import { Conduct } from "./conduct"
6 |
7 | storiesOf("Conduct", module)
8 | .addDecorator((fn) => {fn()})
9 | .add("Style Presets", () => (
10 |
11 |
12 |
13 |
14 |
15 | ))
16 |
--------------------------------------------------------------------------------
/app/components/conduct/conduct.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { TextStyle, TouchableOpacityProps, View, ViewStyle } from "react-native"
3 | import { Text } from "../text/text"
4 | import { Button } from "../button/button"
5 | import { palette, spacing } from "../../theme"
6 |
7 | const ROOT: ViewStyle = {
8 | marginTop: spacing.huge,
9 | paddingHorizontal: spacing.large,
10 | }
11 |
12 | const HEADER: TextStyle = {
13 | color: palette.white,
14 | }
15 | const BODY: TextStyle = {
16 | marginTop: spacing.medium,
17 | marginBottom: spacing.medium,
18 | }
19 |
20 | export function Conduct(props: TouchableOpacityProps) {
21 | return (
22 |
23 |
24 |
25 |
26 |
27 | )
28 | }
29 |
--------------------------------------------------------------------------------
/app/components/contact/contact.story.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { storiesOf } from "@storybook/react-native"
3 | import { Story, StoryScreen, UseCase } from "../../../storybook/views"
4 | import { Contact } from "./contact"
5 |
6 | storiesOf("Code of Conduct - Contact", module)
7 | .addDecorator((fn) => {fn()})
8 | .add("Presets", () => (
9 |
10 |
11 |
12 |
13 |
14 | ))
15 |
--------------------------------------------------------------------------------
/app/components/content-link/content-link.story.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { storiesOf } from "@storybook/react-native"
3 | import { StoryScreen, Story, UseCase } from "../../../storybook/views"
4 | import { ContentLink } from "./content-link"
5 |
6 | storiesOf("ContentLink", module)
7 | .addDecorator((fn) => {fn()})
8 | .add("Style Presets", () => (
9 |
10 |
11 | {}}
13 | headerTx="venueScreen.blog.title"
14 | bodyTx="venueScreen.blog.description"
15 | buttonTx="venueScreen.blog.button"
16 | />
17 |
18 |
19 | ))
20 |
--------------------------------------------------------------------------------
/app/components/content-link/content-link.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { TextStyle, View, ViewStyle } from "react-native"
3 | import { Text } from "../text/text"
4 | import { Button } from "../button/button"
5 | import { palette, spacing } from "../../theme"
6 | import { TxKeyPath } from "../../i18n"
7 |
8 | const ROOT: ViewStyle = {
9 | marginTop: spacing.huge,
10 | paddingHorizontal: spacing.large,
11 | }
12 |
13 | const HEADER: TextStyle = {
14 | color: palette.white,
15 | }
16 | const BODY: TextStyle = {
17 | marginTop: spacing.medium,
18 | marginBottom: spacing.medium,
19 | }
20 |
21 | export function ContentLink(props: {
22 | headerTx: TxKeyPath
23 | bodyTx: TxKeyPath
24 | buttonTx: TxKeyPath
25 | style?: ViewStyle
26 | onPressLink: () => void
27 | }) {
28 | return (
29 |
30 |
31 |
32 |
33 |
34 | )
35 | }
36 |
--------------------------------------------------------------------------------
/app/components/footer/footer.presets.ts:
--------------------------------------------------------------------------------
1 | import { ViewStyle } from "react-native"
2 | import { color } from "../../theme"
3 |
4 | /**
5 | * All text will start off looking like this.
6 | */
7 | const BASE_VIEW: ViewStyle = {
8 | justifyContent: "flex-start",
9 | alignItems: "center",
10 | alignSelf: "flex-end",
11 | width: "100%",
12 | height: 86,
13 | paddingTop: 16,
14 | paddingHorizontal: 20,
15 | }
16 |
17 | /**
18 | * All the variations of text styling within the app.
19 | *
20 | * You want to customize these to whatever you need in your app.
21 | */
22 | export const viewPresets = {
23 | /**
24 | * A smaller piece of secondard information.
25 | */
26 | dark: { ...BASE_VIEW, backgroundColor: color.palette.ebony } as ViewStyle,
27 | }
28 |
29 | /**
30 | * A list of preset names.
31 | */
32 | export type FooterPresetNames = keyof typeof viewPresets
33 |
--------------------------------------------------------------------------------
/app/components/footer/footer.props.ts:
--------------------------------------------------------------------------------
1 | import { ViewProperties, ViewStyle } from "react-native"
2 | import { FooterPresetNames } from "./footer.presets"
3 |
4 | export interface FooterProps extends ViewProperties {
5 | /**
6 | * The children to display if not using `tx` or nested components.
7 | */
8 | children?: object
9 |
10 | /**
11 | * An optional style override useful for padding & margin.
12 | */
13 | style?: ViewStyle
14 |
15 | /**
16 | * One of the different types of text presets.
17 | */
18 | preset?: FooterPresetNames
19 | }
20 |
--------------------------------------------------------------------------------
/app/components/footer/footer.story.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { storiesOf } from "@storybook/react-native"
3 | import { Story, StoryScreen, UseCase } from "../../../storybook/views"
4 | import { Footer } from "./footer"
5 | import { Text } from "../text/text"
6 |
7 | storiesOf("Footer", module)
8 | .addDecorator((fn) => {fn()})
9 | .add("Presets", () => (
10 |
11 |
12 |
13 |
14 |
15 |
18 |
19 |
20 | ))
21 |
--------------------------------------------------------------------------------
/app/components/footer/footer.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { View } from "react-native"
3 | import { viewPresets } from "./footer.presets"
4 | import { FooterProps } from "./footer.props"
5 |
6 | /**
7 | * For your text displaying needs.
8 | *
9 | * This component is a HOC over the built-in React Native one.
10 | */
11 | export function Footer(props: FooterProps) {
12 | // grab the props
13 | const { preset = "dark", children, style: styleOverride, ...rest } = props
14 |
15 | // assemble the style
16 | const viewPresetToUse = viewPresets[preset] || viewPresets.dark
17 |
18 | const viewStyle = { ...viewPresetToUse, ...styleOverride }
19 |
20 | return (
21 |
22 | {children}
23 |
24 | )
25 | }
26 |
--------------------------------------------------------------------------------
/app/components/footer/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./footer"
2 |
--------------------------------------------------------------------------------
/app/components/form-row/form-row.presets.ts:
--------------------------------------------------------------------------------
1 | import { ViewStyle } from "react-native"
2 | import { color, spacing } from "../../theme"
3 |
4 | /**
5 | * The size of the border radius.
6 | */
7 | const RADIUS = 8
8 |
9 | /**
10 | * The default style of the container.
11 | */
12 | const ROOT: ViewStyle = {
13 | borderWidth: 1,
14 | borderColor: color.line,
15 | padding: spacing[2],
16 | }
17 |
18 | /**
19 | * What each of the presets look like.
20 | */
21 | export const PRESETS = {
22 | /**
23 | * Rounded borders on the the top only.
24 | */
25 | top: {
26 | ...ROOT,
27 | borderTopLeftRadius: RADIUS,
28 | borderTopRightRadius: RADIUS,
29 | borderBottomWidth: 0,
30 | },
31 | /**
32 | * No rounded borders.
33 | */
34 | middle: {
35 | ...ROOT,
36 | borderBottomWidth: 0,
37 | },
38 | /**
39 | * Rounded borders on the bottom.
40 | */
41 | bottom: {
42 | ...ROOT,
43 | borderBottomLeftRadius: RADIUS,
44 | borderBottomRightRadius: RADIUS,
45 | },
46 | /**
47 | * Rounded borders everywhere.
48 | */
49 | soloRound: {
50 | ...ROOT,
51 | borderRadius: RADIUS,
52 | },
53 | /**
54 | * Straight borders everywhere.
55 | */
56 | soloStraight: {
57 | ...ROOT,
58 | },
59 | /**
60 | * Transparent borders useful to keep things lined up.
61 | */
62 | clear: {
63 | ...ROOT,
64 | borderColor: color.transparent,
65 | },
66 | }
67 |
68 | /**
69 | * The names of the presets supported by FormRow.
70 | */
71 | export type FormRowPresets = keyof typeof PRESETS
72 |
--------------------------------------------------------------------------------
/app/components/form-row/form-row.props.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { StyleProp, ViewStyle } from "react-native"
3 | import { FormRowPresets } from "./form-row.presets"
4 |
5 | /**
6 | * The properties you can pass to FormRow.
7 | */
8 | export interface FormRowProps {
9 | /**
10 | * Children components.
11 | */
12 | children?: React.ReactNode
13 |
14 | /**
15 | * Override the container style... useful for margins and padding.
16 | */
17 | style?: StyleProp
18 |
19 | /**
20 | * The type of border.
21 | */
22 | preset: FormRowPresets
23 | }
24 |
--------------------------------------------------------------------------------
/app/components/form-row/form-row.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { View } from "react-native"
3 | import { PRESETS } from "./form-row.presets"
4 | import { FormRowProps } from "./form-row.props"
5 |
6 | /**
7 | * A horizontal container component used to hold a row of a form.
8 | */
9 | export function FormRow(props: FormRowProps) {
10 | const viewStyle = [PRESETS[props.preset], props.style]
11 |
12 | return {props.children}
13 | }
14 |
--------------------------------------------------------------------------------
/app/components/gerding-theater/gerding-theater.story.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { storiesOf } from "@storybook/react-native"
3 | import { StoryScreen, Story, UseCase } from "../../../storybook/views"
4 | import { GerdingTheater } from "./gerding-theater"
5 |
6 | storiesOf("GerdingTheater", module)
7 | .addDecorator((fn) => {fn()})
8 | .add("Style Presets", () => (
9 |
10 |
11 |
12 |
13 |
14 | ))
15 |
--------------------------------------------------------------------------------
/app/components/gerding-theater/gerding-theater.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { Image, ImageStyle, TextStyle, View, ViewStyle } from "react-native"
3 | import { Text } from "../text/text"
4 | import { spacing } from "../../theme"
5 |
6 | const venue = require("./img.venue.png")
7 |
8 | const ROOT: ViewStyle = {
9 | flex: 1,
10 | marginTop: spacing.extraLarge,
11 | paddingHorizontal: spacing.large,
12 | marginBottom: 49,
13 | }
14 | const VENUE_STYLE: ImageStyle = {
15 | width: 314,
16 | height: 265,
17 | position: "absolute",
18 | top: 10,
19 | right: -spacing.large,
20 | }
21 | const TITLE: TextStyle = {
22 | marginTop: 223,
23 | }
24 | const DESCRIPTION: TextStyle = {
25 | marginTop: spacing.large,
26 | }
27 |
28 | export const GerdingTheater = () => {
29 | return (
30 |
31 |
32 |
33 |
34 |
35 | )
36 | }
37 |
--------------------------------------------------------------------------------
/app/components/gerding-theater/img.venue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/gerding-theater/img.venue.png
--------------------------------------------------------------------------------
/app/components/gerding-theater/img.venue@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/gerding-theater/img.venue@2x.png
--------------------------------------------------------------------------------
/app/components/gerding-theater/img.venue@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/gerding-theater/img.venue@3x.png
--------------------------------------------------------------------------------
/app/components/getting-to-chain-react/getting-to-chain-react.story.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { storiesOf } from "@storybook/react-native"
3 | import { StoryScreen, Story, UseCase } from "../../../storybook/views"
4 | import { GettingToChainReact } from "./getting-to-chain-react"
5 |
6 | storiesOf("GettingToChainReact", module)
7 | .addDecorator((fn) => {fn()})
8 | .add("Style Presets", () => (
9 |
10 |
11 |
12 |
13 |
14 | ))
15 |
--------------------------------------------------------------------------------
/app/components/getting-to-chain-react/logo-lyft@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/getting-to-chain-react/logo-lyft@1x.png
--------------------------------------------------------------------------------
/app/components/getting-to-chain-react/logo-lyft@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/getting-to-chain-react/logo-lyft@2x.png
--------------------------------------------------------------------------------
/app/components/getting-to-chain-react/logo-lyft@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/getting-to-chain-react/logo-lyft@3x.png
--------------------------------------------------------------------------------
/app/components/getting-to-chain-react/logo-uber@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/getting-to-chain-react/logo-uber@1x.png
--------------------------------------------------------------------------------
/app/components/getting-to-chain-react/logo-uber@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/getting-to-chain-react/logo-uber@2x.png
--------------------------------------------------------------------------------
/app/components/getting-to-chain-react/logo-uber@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/getting-to-chain-react/logo-uber@3x.png
--------------------------------------------------------------------------------
/app/components/gradient-background/gradient-background.story.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { storiesOf } from "@storybook/react-native"
3 | import { StoryScreen, Story, UseCase } from "../../../storybook/views"
4 | import { GradientBackground } from "./gradient-background"
5 |
6 | declare let module
7 |
8 | storiesOf("GradientBackground", module)
9 | .addDecorator((fn) => {fn()})
10 | .add("Style Presets", () => (
11 |
12 |
13 |
14 |
15 |
16 | ))
17 |
--------------------------------------------------------------------------------
/app/components/gradient-background/gradient-background.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { ViewStyle } from "react-native"
3 | import { LinearGradient } from "expo-linear-gradient"
4 |
5 | const BG_GRADIENT: ViewStyle = { position: "absolute", left: 0, right: 0, top: 0, bottom: 0 }
6 |
7 | export interface GradientBackgroundProps {
8 | colors: string[]
9 | }
10 |
11 | export function GradientBackground(props: GradientBackgroundProps) {
12 | return
13 | }
14 |
--------------------------------------------------------------------------------
/app/components/header/header.props.ts:
--------------------------------------------------------------------------------
1 | import { StyleProp, TextStyle, ViewStyle } from "react-native"
2 | import { IconTypes } from "../icon/icons"
3 | import { TxKeyPath } from "../../i18n"
4 |
5 | export interface HeaderProps {
6 | /**
7 | * Main header, e.g. POWERED BY IGNITE
8 | */
9 | headerTx?: TxKeyPath
10 |
11 | /**
12 | * header non-i18n
13 | */
14 | headerText?: string
15 |
16 | /**
17 | * Icon that should appear on the left
18 | */
19 | leftIcon?: IconTypes
20 |
21 | /**
22 | * What happens when you press the left icon
23 | */
24 | onLeftPress?(): void
25 |
26 | /**
27 | * Icon that should appear on the right
28 | */
29 | rightIcon?: IconTypes
30 |
31 | /**
32 | * What happens when you press the right icon
33 | */
34 | onRightPress?(): void
35 |
36 | /**
37 | * Container style overrides.
38 | */
39 | style?: StyleProp
40 |
41 | /**
42 | * Title style overrides.
43 | */
44 | titleStyle?: StyleProp
45 | }
46 |
--------------------------------------------------------------------------------
/app/components/header/header.story.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { View, Alert } from "react-native"
3 | import { storiesOf } from "@storybook/react-native"
4 | import { StoryScreen, Story, UseCase } from "../../../storybook/views"
5 | import { Header } from "./header"
6 | import { color } from "../../theme"
7 |
8 | declare let module
9 |
10 | const VIEWSTYLE = {
11 | flex: 1,
12 | backgroundColor: color.background,
13 | }
14 |
15 | storiesOf("Header", module)
16 | .addDecorator((fn) => {fn()})
17 | .add("Behavior", () => (
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | Alert.alert("left nav")}
30 | />
31 |
32 |
33 |
34 |
35 | Alert.alert("right nav")}
39 | />
40 |
41 |
42 |
43 | ))
44 |
--------------------------------------------------------------------------------
/app/components/header/header.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { View, ViewStyle, TextStyle } from "react-native"
3 | import { HeaderProps } from "./header.props"
4 | import { Button } from "../button/button"
5 | import { Text } from "../text/text"
6 | import { Icon } from "../icon/icon"
7 | import { spacing } from "../../theme"
8 | import { translate } from "../../i18n/"
9 |
10 | // static styles
11 | const ROOT: ViewStyle = {
12 | flexDirection: "row",
13 | paddingHorizontal: spacing[4],
14 | alignItems: "center",
15 | paddingTop: spacing[5],
16 | paddingBottom: spacing[5],
17 | justifyContent: "flex-start",
18 | }
19 | const TITLE: TextStyle = { textAlign: "center" }
20 | const TITLE_MIDDLE: ViewStyle = { flex: 1, justifyContent: "center" }
21 | const LEFT: ViewStyle = { width: 32 }
22 | const RIGHT: ViewStyle = { width: 32 }
23 |
24 | /**
25 | * Header that appears on many screens. Will hold navigation buttons and screen title.
26 | */
27 | export function Header(props: HeaderProps) {
28 | const {
29 | onLeftPress,
30 | onRightPress,
31 | rightIcon,
32 | leftIcon,
33 | headerText,
34 | headerTx,
35 | style,
36 | titleStyle,
37 | } = props
38 | const header = headerText || (headerTx && translate(headerTx)) || ""
39 |
40 | return (
41 |
42 | {leftIcon ? (
43 |
46 | ) : (
47 |
48 | )}
49 |
50 |
51 |
52 | {rightIcon ? (
53 |
56 | ) : (
57 |
58 | )}
59 |
60 | )
61 | }
62 |
--------------------------------------------------------------------------------
/app/components/icon/icon.props.ts:
--------------------------------------------------------------------------------
1 | import { ImageStyle, StyleProp, ViewStyle } from "react-native"
2 | import { IconTypes } from "./icons"
3 |
4 | export interface IconProps {
5 | /**
6 | * Style overrides for the icon image
7 | */
8 | style?: StyleProp
9 |
10 | /**
11 | * Style overrides for the icon container
12 | */
13 |
14 | containerStyle?: StyleProp
15 |
16 | /**
17 | * The name of the icon
18 | */
19 |
20 | icon?: IconTypes
21 | }
22 |
--------------------------------------------------------------------------------
/app/components/icon/icon.story.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { storiesOf } from "@storybook/react-native"
3 | import { StoryScreen, Story, UseCase } from "../../../storybook/views"
4 | import { Icon } from "./icon"
5 |
6 | declare let module
7 |
8 | storiesOf("Icon", module)
9 | .addDecorator((fn) => {fn()})
10 | .add("Names", () => (
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | ))
20 |
--------------------------------------------------------------------------------
/app/components/icon/icon.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { View, ImageStyle } from "react-native"
3 | import { AutoImage as Image } from "../auto-image/auto-image"
4 | import { IconProps } from "./icon.props"
5 | import { icons } from "./icons"
6 |
7 | const ROOT: ImageStyle = {
8 | resizeMode: "contain",
9 | }
10 |
11 | export function Icon(props: IconProps) {
12 | const { style: styleOverride, icon, containerStyle } = props
13 |
14 | return (
15 |
16 |
17 |
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/app/components/icon/icons/arrow-left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/icon/icons/arrow-left.png
--------------------------------------------------------------------------------
/app/components/icon/icons/arrow-left@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/icon/icons/arrow-left@2x.png
--------------------------------------------------------------------------------
/app/components/icon/icons/bullet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/icon/icons/bullet.png
--------------------------------------------------------------------------------
/app/components/icon/icons/bullet@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/icon/icons/bullet@2x.png
--------------------------------------------------------------------------------
/app/components/icon/icons/index.ts:
--------------------------------------------------------------------------------
1 | export const icons = {
2 | back: require("./arrow-left.png"),
3 | bullet: require("./bullet.png"),
4 | bug: require("./ladybug.png"),
5 | }
6 |
7 | export type IconTypes = keyof typeof icons
8 |
--------------------------------------------------------------------------------
/app/components/icon/icons/ladybug.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/icon/icons/ladybug.png
--------------------------------------------------------------------------------
/app/components/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./bullet-item/bullet-item"
2 | export * from "./button/button"
3 | export * from "./checkbox/checkbox"
4 | export * from "./form-row/form-row"
5 | export * from "./header/header"
6 | export * from "./gradient-background/gradient-background"
7 | export * from "./icon/icon"
8 | export * from "./screen/screen"
9 | export * from "./switch/switch"
10 | export * from "./text/text"
11 | export * from "./text-field/text-field"
12 | export * from "./footer/footer"
13 | export * from "./wallpaper/wallpaper"
14 | export * from "./auto-image/auto-image"
15 | export * from "./tab-icon/tab-icon"
16 | export * from "./schedule-cell/schedule-cell"
17 | export * from "./schedule-nav/schedule-nav"
18 | export * from "./speaker-image/speaker-image"
19 | export * from "./talk-title/talk-title"
20 | export * from "./speaker-bio/speaker-bio"
21 | export * from "./back-button/back-button"
22 | export * from "./title-bar/title-bar"
23 | export * from "./gerding-theater/gerding-theater"
24 | export * from "./getting-to-chain-react/getting-to-chain-react"
25 | export * from "./travel-option/travel-option"
26 | export * from "./nearby-attractions/nearby-attractions"
27 | export * from "./content-link/content-link"
28 | export * from "./presented-by/presented-by"
29 | export * from "./wi-fi/wi-fi"
30 | export * from "./conduct/conduct"
31 | export * from "./sponsors/sponsors"
32 | export * from "./survey-link/survey-link"
33 |
--------------------------------------------------------------------------------
/app/components/nearby-attractions/attraction.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { TextStyle, View, ViewProps, ViewStyle } from "react-native"
3 | import { Text } from "../text/text"
4 | import { Rating } from "./rating"
5 | import { palette } from "../../theme"
6 |
7 | const ROOT: ViewStyle = {
8 | flex: 1,
9 | paddingVertical: 25,
10 | }
11 | const NAME_WRAPPER: ViewStyle = {
12 | flexDirection: "row",
13 | }
14 | const TITLE_WRAPPER: ViewStyle = {
15 | width: "70%",
16 | }
17 | const TITLE: TextStyle = {
18 | color: palette.white,
19 | }
20 | const ADDRESS: TextStyle = {
21 | color: palette.offWhite,
22 | }
23 |
24 | export interface AttractionProps extends ViewProps {
25 | attraction: any
26 | }
27 |
28 | export const Attraction = (props: AttractionProps) => {
29 | const { attraction } = props
30 | const cleanedAddress = attraction.properties.place_address
31 | .replace(", United States", "")
32 | .replace(", Portland, OR", ",\nPortland, OR")
33 | .replace(", Portland, Oregon", ",\nPortland, OR")
34 | return (
35 |
36 |
37 |
38 |
43 |
44 |
45 |
46 |
47 |
48 | )
49 | }
50 |
--------------------------------------------------------------------------------
/app/components/nearby-attractions/images/Close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/nearby-attractions/images/Close.png
--------------------------------------------------------------------------------
/app/components/nearby-attractions/images/Close@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/nearby-attractions/images/Close@2x.png
--------------------------------------------------------------------------------
/app/components/nearby-attractions/images/Close@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/nearby-attractions/images/Close@3x.png
--------------------------------------------------------------------------------
/app/components/nearby-attractions/images/star.filled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/nearby-attractions/images/star.filled.png
--------------------------------------------------------------------------------
/app/components/nearby-attractions/images/star.filled@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/nearby-attractions/images/star.filled@2x.png
--------------------------------------------------------------------------------
/app/components/nearby-attractions/images/star.filled@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/nearby-attractions/images/star.filled@3x.png
--------------------------------------------------------------------------------
/app/components/nearby-attractions/images/star.unfilled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/nearby-attractions/images/star.unfilled.png
--------------------------------------------------------------------------------
/app/components/nearby-attractions/images/star.unfilled@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/nearby-attractions/images/star.unfilled@2x.png
--------------------------------------------------------------------------------
/app/components/nearby-attractions/images/star.unfilled@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/nearby-attractions/images/star.unfilled@3x.png
--------------------------------------------------------------------------------
/app/components/nearby-attractions/nearby-attractions.story.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { storiesOf } from "@storybook/react-native"
3 | import { Story, StoryScreen, UseCase } from "../../../storybook/views"
4 | import { NearbyAttractions } from "./nearby-attractions"
5 |
6 | storiesOf("NearbyAttractions", module)
7 | .addDecorator((fn) => {fn()})
8 | .add("Style Presets", () => (
9 |
10 |
11 |
12 |
13 |
14 | ))
15 |
--------------------------------------------------------------------------------
/app/components/nearby-attractions/nearby-attractions.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { View, ViewStyle } from "react-native"
3 | import { getScreenWidth, palette, spacing } from "../../theme"
4 | import { AttractionsList } from "./attractions-list"
5 | import { AttractionsMap } from "./attractions-map"
6 |
7 | const ROOT: ViewStyle = {
8 | paddingTop: spacing.large,
9 | backgroundColor: palette.portGoreLight,
10 | }
11 |
12 | export const NearbyAttractions = () => {
13 | const fullWidth = {
14 | width: getScreenWidth(),
15 | }
16 | return (
17 |
18 |
19 |
20 |
21 | )
22 | }
23 |
--------------------------------------------------------------------------------
/app/components/nearby-attractions/rating.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { Image, ImageStyle, View, ViewStyle } from "react-native"
3 |
4 | const filled = require("./images/star.filled.png")
5 | const empty = require("./images/star.unfilled.png")
6 |
7 | const ROOT: ViewStyle = {
8 | marginLeft: "auto",
9 | flexDirection: "row",
10 | width: 17 * 5,
11 | height: 11,
12 | }
13 | const STAR: ImageStyle = {
14 | width: 11,
15 | height: 11,
16 | marginLeft: 6,
17 | }
18 |
19 | type RatingProps = { rating?: number }
20 |
21 | export const Rating = (props: RatingProps) => {
22 | const stars = [1, 2, 3, 4, 5]
23 | const { rating } = props
24 |
25 | return (
26 |
27 | {stars.map((i) => (
28 |
29 | ))}
30 |
31 | )
32 | }
33 |
--------------------------------------------------------------------------------
/app/components/nearby-attractions/render-link.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { Linking, TextStyle, TouchableOpacity } from "react-native"
3 | import { Text } from ".."
4 | import { color } from "../../theme"
5 |
6 | const DIRECTIONS: TextStyle = {
7 | fontSize: 11,
8 | lineHeight: 13,
9 | color: color.palette.white,
10 | letterSpacing: 2,
11 | fontWeight: "500",
12 | }
13 |
14 | type RenderLinkProps = {
15 | link: string
16 | }
17 | export const RenderLink = ({ link }: RenderLinkProps) => {
18 | const openLink = () => {
19 | Linking.canOpenURL(link).then((supported) => {
20 | if (!supported) return
21 | Linking.openURL(link)
22 | })
23 | }
24 | return (
25 |
26 |
27 |
28 | )
29 | }
30 |
--------------------------------------------------------------------------------
/app/components/presented-by/images/bg.team.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/presented-by/images/bg.team.png
--------------------------------------------------------------------------------
/app/components/presented-by/images/bg.team@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/presented-by/images/bg.team@2x.png
--------------------------------------------------------------------------------
/app/components/presented-by/images/bg.team@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/presented-by/images/bg.team@3x.png
--------------------------------------------------------------------------------
/app/components/presented-by/images/logo.infinitered.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/presented-by/images/logo.infinitered.png
--------------------------------------------------------------------------------
/app/components/presented-by/images/logo.infinitered@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/presented-by/images/logo.infinitered@2x.png
--------------------------------------------------------------------------------
/app/components/presented-by/images/logo.infinitered@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/presented-by/images/logo.infinitered@3x.png
--------------------------------------------------------------------------------
/app/components/presented-by/presented-by.presets.ts:
--------------------------------------------------------------------------------
1 | import { ViewStyle } from "react-native"
2 | import { spacing } from "../../theme"
3 |
4 | /**
5 | * All text will start off looking like this.
6 | */
7 | const BASE_VIEW: ViewStyle = {
8 | flex: 1,
9 | justifyContent: "center",
10 | marginTop: spacing.ginormous + spacing.large,
11 | paddingHorizontal: spacing.large,
12 | }
13 |
14 | /**
15 | * All the variations of text styling within the app.
16 | *
17 | * You want to customize these to whatever you need in your app.
18 | */
19 | export const presentedByPresets = {
20 | /**
21 | * A smaller piece of secondard information.
22 | */
23 | default: { ...BASE_VIEW } as ViewStyle,
24 | }
25 |
26 | /**
27 | * A list of preset names.
28 | */
29 | export type PresentedByPresetNames = keyof typeof presentedByPresets
30 |
--------------------------------------------------------------------------------
/app/components/presented-by/presented-by.story.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { storiesOf } from "@storybook/react-native"
3 | import { Story, StoryScreen, UseCase } from "../../../storybook/views"
4 | import { PresentedBy } from "./presented-by"
5 |
6 | storiesOf("PresentedBy", module)
7 | .addDecorator((fn) => {fn()})
8 | .add("Presets", () => (
9 |
10 |
11 |
12 |
13 |
14 | ))
15 |
--------------------------------------------------------------------------------
/app/components/schedule-cell/images/afterparty-G2i.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/schedule-cell/images/afterparty-G2i.png
--------------------------------------------------------------------------------
/app/components/schedule-cell/images/coffee-small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/schedule-cell/images/coffee-small.png
--------------------------------------------------------------------------------
/app/components/schedule-cell/images/lunch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/schedule-cell/images/lunch.png
--------------------------------------------------------------------------------
/app/components/schedule-cell/images/panelist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/schedule-cell/images/panelist.png
--------------------------------------------------------------------------------
/app/components/schedule-cell/images/registration.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/schedule-cell/images/registration.png
--------------------------------------------------------------------------------
/app/components/schedule-cell/images/sponsor-bumped.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/schedule-cell/images/sponsor-bumped.png
--------------------------------------------------------------------------------
/app/components/schedule-cell/render-image.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { Image, ImageStyle } from "react-native"
3 | import { Event } from "../../models"
4 | import { ScheduleCellPresets } from "./schedule-cell.presets"
5 |
6 | type RenderImageProps = {
7 | preset: keyof typeof ScheduleCellPresets
8 | event: Event
9 | }
10 | export const RenderImage = (props: RenderImageProps) => {
11 | const {
12 | preset,
13 | event: { sponsor, eventType, speakers },
14 | event,
15 | } = props
16 |
17 | const style: any = ScheduleCellPresets[preset] || ScheduleCellPresets.default
18 | let image = null
19 |
20 | if (eventType === "panel") {
21 | image = require("./images/panelist.png")
22 | } else if (eventType === "afterparty") {
23 | if (sponsor === "G2i") image = require("./images/afterparty-G2i.png")
24 | if (sponsor === "Bumped") image = require("./images/sponsor-bumped.png")
25 | } else if (eventType === "break") {
26 | image = require("./images/coffee-small.png")
27 | } else if (["talk", "workshop", "welcome", "goodbye"].includes(eventType)) {
28 | image = speakers && speakers[0] && speakers[0].image ? { uri: speakers[0].image } : null
29 | } else if (eventType === "lunch") {
30 | image = require("./images/lunch.png")
31 | } else if (eventType === "breakfast") {
32 | image = require("./images/registration.png")
33 | } else {
34 | if (event.image) image = { uri: event.image }
35 | }
36 | if (image) {
37 | return
38 | } else {
39 | return null
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/app/components/schedule-cell/render-time.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { TextStyle, View, ViewStyle } from "react-native"
3 | import { Text } from ".."
4 | import { Event } from "../../models"
5 | import { ScheduleCellPresets } from "./schedule-cell.presets"
6 |
7 | type RenderTimeProps = {
8 | preset: keyof typeof ScheduleCellPresets
9 | event: Event
10 | }
11 |
12 | export const RenderTime = (props: RenderTimeProps) => {
13 | const { preset, event } = props
14 | const style: any = ScheduleCellPresets[preset] || ScheduleCellPresets.default
15 | const label = `${event.startTime}`
16 |
17 | return (
18 |
19 | {event.track && }
20 |
21 |
22 | )
23 | }
24 |
--------------------------------------------------------------------------------
/app/components/schedule-cell/schedule-cell.props.ts:
--------------------------------------------------------------------------------
1 | import { ViewProps } from "react-native"
2 | import { Event } from "../../models"
3 | import { ScheduleCellPresetNames } from "./schedule-cell.presets"
4 |
5 | export interface ScheduleCellProps extends ViewProps {
6 | // Index to determine if cell is even or odd
7 | index: number
8 | event: Event
9 | preset?: ScheduleCellPresetNames
10 | onPress: (event: Event) => void
11 | noTime?: boolean
12 | }
13 |
--------------------------------------------------------------------------------
/app/components/schedule-nav/schedule-nav.story.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { storiesOf } from "@storybook/react-native"
3 | import { StoryScreen, Story, UseCase } from "../../../storybook/views"
4 | import { ScheduleNav } from "./schedule-nav"
5 |
6 | storiesOf("ScheduleNav", module)
7 | .addDecorator((fn) => {fn()})
8 | .add("Style Presets", () => (
9 |
10 |
11 | {}} />
12 |
13 |
14 | ))
15 |
--------------------------------------------------------------------------------
/app/components/schedule-nav/schedule-nav.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { TextStyle, TouchableOpacity, View, ViewStyle } from "react-native"
3 | import { Text } from "../text/text"
4 | import { palette, spacing } from "../../theme"
5 | import { EVENT_DAYS } from "../../models"
6 |
7 | const NAV_WRAPPER: ViewStyle = {
8 | flexDirection: "row",
9 | }
10 |
11 | const NAV_BUTTON: ViewStyle = {
12 | flex: 1,
13 | justifyContent: "center",
14 | alignItems: "center",
15 | backgroundColor: palette.lightGrey,
16 | paddingTop: spacing.large,
17 | paddingBottom: spacing.medium,
18 | borderRightColor: palette.offWhite,
19 | borderRightWidth: 1,
20 | }
21 |
22 | const NAV_BUTTON_SELECTED: ViewStyle = {
23 | backgroundColor: palette.shamrock,
24 | }
25 |
26 | const NAV_BUTTON_LAST: ViewStyle = {
27 | borderRightWidth: 0,
28 | }
29 |
30 | const NAV_TEXT: TextStyle = {
31 | color: palette.haiti,
32 | }
33 |
34 | type ScheduleNavProps = {
35 | selected: EVENT_DAYS
36 | onSelected: (selected: EVENT_DAYS) => void
37 | }
38 | export const ScheduleNav = ({ selected, onSelected }: ScheduleNavProps) => {
39 | return (
40 |
41 | onSelected("wednesday")}
44 | >
45 |
46 |
47 | onSelected("thursday")}
50 | >
51 |
52 |
53 | onSelected("friday")}
56 | >
57 |
58 |
59 |
60 | )
61 | }
62 |
--------------------------------------------------------------------------------
/app/components/screen/screen.props.ts:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { StyleProp, ViewStyle } from "react-native"
3 | import { KeyboardOffsets, ScreenPresets } from "./screen.presets"
4 |
5 | export interface ScreenProps {
6 | /**
7 | * Children components.
8 | */
9 | children?: React.ReactNode
10 |
11 | /**
12 | * An optional style override useful for padding & margin.
13 | */
14 | style?: StyleProp
15 |
16 | /**
17 | * One of the different types of presets.
18 | */
19 | preset?: ScreenPresets
20 |
21 | /**
22 | * An optional background color
23 | */
24 | backgroundColor?: string
25 |
26 | /**
27 | * An optional background image
28 | */
29 | backgroundImage?: any
30 |
31 | /**
32 | * An optional status bar setting. Defaults to light-content.
33 | */
34 | statusBar?: "light-content" | "dark-content"
35 |
36 | /**
37 | * Should we not wrap in SafeAreaView? Defaults to false.
38 | */
39 | unsafe?: boolean
40 |
41 | /**
42 | * By how much should we offset the keyboard? Defaults to none.
43 | */
44 | keyboardOffset?: KeyboardOffsets
45 |
46 | /**
47 | * Should keyboard persist on screen tap. Defaults to handled.
48 | * Only applies to scroll preset.
49 | */
50 | keyboardShouldPersistTaps?: "handled" | "always" | "never"
51 | }
52 |
--------------------------------------------------------------------------------
/app/components/social-button/social-button.presets.ts:
--------------------------------------------------------------------------------
1 | import { ViewStyle } from "react-native"
2 |
3 | /**
4 | * All text will start off looking like this.
5 | */
6 | const BASE_VIEW: ViewStyle = {
7 | width: 32,
8 | height: 32,
9 | justifyContent: "center",
10 | alignItems: "center",
11 | }
12 |
13 | /**
14 | * All the variations of text styling within the app.
15 | *
16 | * You want to customize these to whatever you need in your app.
17 | */
18 | export const viewPresets = {
19 | /**
20 | * A smaller piece of secondard information.
21 | */
22 | default: { ...BASE_VIEW } as ViewStyle,
23 | }
24 |
25 | export const imageSource = {
26 | websites: require("./social_icon_assets/link.png"),
27 | website: require("./social_icon_assets/link.png"),
28 | twitter: require("./social_icon_assets/twitter.png"),
29 | github: require("./social_icon_assets/github.png"),
30 | medium: require("./social_icon_assets/medium.png"),
31 | dribbble: require("./social_icon_assets/dribbble.png"),
32 | instagram: require("./social_icon_assets/instagram.png"),
33 | facebook: require("./social_icon_assets/facebook.png"),
34 | email: require("./social_icon_assets/email.icon.png"),
35 | phone: require("./social_icon_assets/phone.icon.png"),
36 | slack: require("./social_icon_assets/slack.png"),
37 | }
38 |
39 | export const imageStyle = {
40 | default: {},
41 | }
42 |
43 | /**
44 | * A list of preset names.
45 | */
46 | export type SocialButtonPresetNames = keyof typeof imageSource
47 |
--------------------------------------------------------------------------------
/app/components/social-button/social-button.props.ts:
--------------------------------------------------------------------------------
1 | import { TouchableOpacityProperties } from "react-native"
2 | import { SocialButtonPresetNames } from "./social-button.presets"
3 |
4 | export interface SocialButtonProps extends TouchableOpacityProperties {
5 | /**
6 | * One of the different types of text presets.
7 | */
8 | preset?: SocialButtonPresetNames
9 | link: string
10 | }
11 |
--------------------------------------------------------------------------------
/app/components/social-button/social-button.story.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { storiesOf } from "@storybook/react-native"
3 | import { Story, StoryScreen, UseCase } from "../../../storybook/views"
4 | import { SocialButton } from "./social-button"
5 |
6 | storiesOf("SocialButton", module)
7 | .addDecorator((fn) => {fn()})
8 | .add("Presets", () => (
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | ))
36 |
--------------------------------------------------------------------------------
/app/components/social-button/social-button.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { Image, Linking, TouchableHighlight } from "react-native"
3 | import { imageSource, imageStyle, viewPresets } from "./social-button.presets"
4 | import { SocialButtonProps } from "./social-button.props"
5 | import { HIT_SLOP } from "../../theme"
6 |
7 | /**
8 | * Link to social media, using a social media logo.
9 | */
10 | export function SocialButton(props: SocialButtonProps) {
11 | // grab the props
12 | const { preset = "website", link, style, ...rest } = props
13 |
14 | const image = imageSource[preset] || imageSource["website"]
15 |
16 | return (
17 | Linking.openURL(link)}
20 | hitSlop={HIT_SLOP}
21 | {...rest}
22 | >
23 |
24 |
25 | )
26 | }
27 |
--------------------------------------------------------------------------------
/app/components/social-button/social_icon_assets/dribbble.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/social-button/social_icon_assets/dribbble.png
--------------------------------------------------------------------------------
/app/components/social-button/social_icon_assets/dribbble@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/social-button/social_icon_assets/dribbble@2x.png
--------------------------------------------------------------------------------
/app/components/social-button/social_icon_assets/dribbble@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/social-button/social_icon_assets/dribbble@3x.png
--------------------------------------------------------------------------------
/app/components/social-button/social_icon_assets/email.icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/social-button/social_icon_assets/email.icon.png
--------------------------------------------------------------------------------
/app/components/social-button/social_icon_assets/email.icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/social-button/social_icon_assets/email.icon@2x.png
--------------------------------------------------------------------------------
/app/components/social-button/social_icon_assets/email.icon@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/social-button/social_icon_assets/email.icon@3x.png
--------------------------------------------------------------------------------
/app/components/social-button/social_icon_assets/facebook.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/social-button/social_icon_assets/facebook.png
--------------------------------------------------------------------------------
/app/components/social-button/social_icon_assets/facebook@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/social-button/social_icon_assets/facebook@2x.png
--------------------------------------------------------------------------------
/app/components/social-button/social_icon_assets/facebook@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/social-button/social_icon_assets/facebook@3x.png
--------------------------------------------------------------------------------
/app/components/social-button/social_icon_assets/github.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/social-button/social_icon_assets/github.png
--------------------------------------------------------------------------------
/app/components/social-button/social_icon_assets/github@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/social-button/social_icon_assets/github@2x.png
--------------------------------------------------------------------------------
/app/components/social-button/social_icon_assets/github@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/social-button/social_icon_assets/github@3x.png
--------------------------------------------------------------------------------
/app/components/social-button/social_icon_assets/instagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/social-button/social_icon_assets/instagram.png
--------------------------------------------------------------------------------
/app/components/social-button/social_icon_assets/instagram@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/social-button/social_icon_assets/instagram@2x.png
--------------------------------------------------------------------------------
/app/components/social-button/social_icon_assets/instagram@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/social-button/social_icon_assets/instagram@3x.png
--------------------------------------------------------------------------------
/app/components/social-button/social_icon_assets/link.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/social-button/social_icon_assets/link.png
--------------------------------------------------------------------------------
/app/components/social-button/social_icon_assets/link@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/social-button/social_icon_assets/link@2x.png
--------------------------------------------------------------------------------
/app/components/social-button/social_icon_assets/link@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/social-button/social_icon_assets/link@3x.png
--------------------------------------------------------------------------------
/app/components/social-button/social_icon_assets/medium.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/social-button/social_icon_assets/medium.png
--------------------------------------------------------------------------------
/app/components/social-button/social_icon_assets/medium@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/social-button/social_icon_assets/medium@2x.png
--------------------------------------------------------------------------------
/app/components/social-button/social_icon_assets/medium@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/social-button/social_icon_assets/medium@3x.png
--------------------------------------------------------------------------------
/app/components/social-button/social_icon_assets/phone.icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/social-button/social_icon_assets/phone.icon.png
--------------------------------------------------------------------------------
/app/components/social-button/social_icon_assets/phone.icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/social-button/social_icon_assets/phone.icon@2x.png
--------------------------------------------------------------------------------
/app/components/social-button/social_icon_assets/phone.icon@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/social-button/social_icon_assets/phone.icon@3x.png
--------------------------------------------------------------------------------
/app/components/social-button/social_icon_assets/slack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/social-button/social_icon_assets/slack.png
--------------------------------------------------------------------------------
/app/components/social-button/social_icon_assets/slack@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/social-button/social_icon_assets/slack@2x.png
--------------------------------------------------------------------------------
/app/components/social-button/social_icon_assets/slack@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/social-button/social_icon_assets/slack@3x.png
--------------------------------------------------------------------------------
/app/components/social-button/social_icon_assets/twitter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/social-button/social_icon_assets/twitter.png
--------------------------------------------------------------------------------
/app/components/social-button/social_icon_assets/twitter@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/social-button/social_icon_assets/twitter@2x.png
--------------------------------------------------------------------------------
/app/components/social-button/social_icon_assets/twitter@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/social-button/social_icon_assets/twitter@3x.png
--------------------------------------------------------------------------------
/app/components/speaker-image/img.speaker.lg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/speaker-image/img.speaker.lg.png
--------------------------------------------------------------------------------
/app/components/speaker-image/img.speaker.lg@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/speaker-image/img.speaker.lg@2x.png
--------------------------------------------------------------------------------
/app/components/speaker-image/img.speaker.lg@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/speaker-image/img.speaker.lg@3x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Additional_AWS_AA_AfterParty.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Additional_AWS_AA_AfterParty.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Additional_AWS_AA_AfterParty@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Additional_AWS_AA_AfterParty@2x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Additional_AWS_AA_AfterParty@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Additional_AWS_AA_AfterParty@3x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Additional_DevLifts_Streches.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Additional_DevLifts_Streches.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Additional_DevLifts_Streches@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Additional_DevLifts_Streches@2x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Additional_DevLifts_Streches@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Additional_DevLifts_Streches@3x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Additional_G2i.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Additional_G2i.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Additional_G2i@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Additional_G2i@2x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Additional_G2i@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Additional_G2i@3x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Additional_Playstation_Wifi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Additional_Playstation_Wifi.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Additional_Playstation_Wifi@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Additional_Playstation_Wifi@2x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Additional_Playstation_Wifi@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Additional_Playstation_Wifi@3x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Additional_SquarespaceBadges.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Additional_SquarespaceBadges.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Additional_SquarespaceBadges@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Additional_SquarespaceBadges@2x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Additional_SquarespaceBadges@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Additional_SquarespaceBadges@3x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Additional_bumped-alt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Additional_bumped-alt.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Additional_bumped-alt@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Additional_bumped-alt@2x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Additional_bumped-alt@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Additional_bumped-alt@3x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Bronze_Airship.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Bronze_Airship.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Bronze_Airship@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Bronze_Airship@2x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Bronze_Airship@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Bronze_Airship@3x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Bronze_BuilderX.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Bronze_BuilderX.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Bronze_BuilderX@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Bronze_BuilderX@2x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Bronze_BuilderX@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Bronze_BuilderX@3x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Bronze_Cambia.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Bronze_Cambia.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Bronze_Cambia@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Bronze_Cambia@2x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Bronze_Cambia@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Bronze_Cambia@3x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Bronze_Echobind.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Bronze_Echobind.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Bronze_Echobind@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Bronze_Echobind@2x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Bronze_Echobind@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Bronze_Echobind@3x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Bronze_Facebook.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Bronze_Facebook.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Bronze_Facebook@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Bronze_Facebook@2x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Bronze_Facebook@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Bronze_Facebook@3x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Bronze_G2i.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Bronze_G2i.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Bronze_G2i@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Bronze_G2i@2x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Bronze_G2i@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Bronze_G2i@3x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Bronze_Modus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Bronze_Modus.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Bronze_Modus@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Bronze_Modus@2x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Bronze_Modus@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Bronze_Modus@3x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Gold_Callstack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Gold_Callstack.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Gold_Callstack@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Gold_Callstack@2x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Gold_Callstack@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Gold_Callstack@3x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Gold_Coinbase.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Gold_Coinbase.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Gold_Coinbase@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Gold_Coinbase@2x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Gold_Coinbase@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Gold_Coinbase@3x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Gold_Sentry.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Gold_Sentry.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Gold_Sentry@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Gold_Sentry@2x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Gold_Sentry@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Gold_Sentry@3x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Platinum_AWS.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Platinum_AWS.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Platinum_AWS@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Platinum_AWS@2x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Platinum_AWS@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Platinum_AWS@3x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Platinum_Amazon_Alexa.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Platinum_Amazon_Alexa.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Platinum_Amazon_Alexa@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Platinum_Amazon_Alexa@2x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Platinum_Amazon_Alexa@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Platinum_Amazon_Alexa@3x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Silver_AmazonWebService.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Silver_AmazonWebService.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Silver_AmazonWebService@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Silver_AmazonWebService@2x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Silver_AmazonWebService@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Silver_AmazonWebService@3x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Silver_Bugsnag.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Silver_Bugsnag.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Silver_Bugsnag@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Silver_Bugsnag@2x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Silver_Bugsnag@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Silver_Bugsnag@3x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Silver_GoDaddy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Silver_GoDaddy.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Silver_GoDaddy@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Silver_GoDaddy@2x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Silver_GoDaddy@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Silver_GoDaddy@3x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Silver_ServerlessGuru.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Silver_ServerlessGuru.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Silver_ServerlessGuru@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Silver_ServerlessGuru@2x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/Silver_ServerlessGuru@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/Silver_ServerlessGuru@3x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/playstation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/playstation.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/playstation@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/playstation@2x.png
--------------------------------------------------------------------------------
/app/components/sponsors/logos/playstation@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/sponsors/logos/playstation@3x.png
--------------------------------------------------------------------------------
/app/components/sponsors/sponsor-logo.presets.ts:
--------------------------------------------------------------------------------
1 | import { ImageStyle } from "react-native"
2 | import { spacing } from "../../theme"
3 | /**
4 | * All the variations of text styling within the app.
5 | *
6 | * You want to customize these to whatever you need in your app.
7 | */
8 | const BASE: ImageStyle = {
9 | flex: 1,
10 | resizeMode: "contain",
11 | alignSelf: "center",
12 | margin: spacing.small,
13 | }
14 |
15 | export const sponsorLogoSizePresets = {
16 | platinum: {
17 | ...BASE,
18 | width: "100%",
19 | maxHeight: 135,
20 | marginVertical: spacing.medium,
21 | } as ImageStyle,
22 | gold: { ...BASE, height: 75, maxWidth: "50%" },
23 | silver: { ...BASE, height: 50, maxWidth: "35%" },
24 | bronze: { ...BASE, maxHeight: 35, maxWidth: "30%" },
25 | additional: { ...BASE, height: 60 },
26 | }
27 |
28 | export const sponsors = {
29 | airship: require("./logos/Bronze_Airship.png"),
30 | alexa: require("./logos/Platinum_Amazon_Alexa.png"),
31 | amazonWeb: require("./logos/Silver_AmazonWebService.png"),
32 | aws: require("./logos/Platinum_AWS.png"),
33 | bugsnag: require("./logos/Silver_Bugsnag.png"),
34 | builderX: require("./logos/Bronze_BuilderX.png"),
35 | bumped: require("./logos/Additional_bumped-alt.png"),
36 | callstack: require("./logos/Gold_Callstack.png"),
37 | cambia: require("./logos/Bronze_Cambia.png"),
38 | coinbase: require("./logos/Gold_Coinbase.png"),
39 | devLifts: require("./logos/Additional_DevLifts_Streches.png"),
40 | echobind: require("./logos/Bronze_Echobind.png"),
41 | facebook: require("./logos/Bronze_Facebook.png"),
42 | g2i: require("./logos/Bronze_G2i.png"),
43 | g2iAdditional: require("./logos/Additional_G2i.png"),
44 | goDaddy: require("./logos/Silver_GoDaddy.png"),
45 | modus: require("./logos/Bronze_Modus.png"),
46 | playstation: require("./logos/Additional_Playstation_Wifi.png"),
47 | sentry: require("./logos/Gold_Sentry.png"),
48 | serverlessGuru: require("./logos/Silver_ServerlessGuru.png"),
49 | squarespace: require("./logos/Additional_SquarespaceBadges.png"),
50 | }
51 |
52 | export type SponsorLogoSizePresetNames = keyof typeof sponsorLogoSizePresets
53 | export type SponsorNames = keyof typeof sponsors
54 |
--------------------------------------------------------------------------------
/app/components/sponsors/sponsor-logo.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { Image, ImageStyle, TextStyle, View, ViewStyle } from "react-native"
3 | import { Text } from "../text/text"
4 | import {
5 | SponsorLogoSizePresetNames,
6 | sponsorLogoSizePresets,
7 | SponsorNames,
8 | sponsors,
9 | } from "./sponsor-logo.presets"
10 | import { color } from "../../theme"
11 |
12 | const ROOT: ViewStyle = {
13 | flexDirection: "column",
14 | width: "50%",
15 | alignItems: "center",
16 | }
17 |
18 | const SUBTITLE: TextStyle = {
19 | fontSize: 12,
20 | fontWeight: "600",
21 | letterSpacing: 3.0,
22 | color: color.palette.shamrock,
23 | }
24 |
25 | export type SponsorLogoProps = {
26 | size?: SponsorLogoSizePresetNames
27 | sponsor?: SponsorNames
28 | style?: ImageStyle
29 | subtitle?: string
30 | }
31 |
32 | export const SponsorLogo = (props: SponsorLogoProps) => {
33 | const { size, sponsor, style, subtitle } = props
34 | if (!subtitle) {
35 | return (
36 |
37 | )
38 | } else {
39 | return (
40 |
41 |
45 | {subtitle && }
46 |
47 | )
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/app/components/sponsors/sponsors.story.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { storiesOf } from "@storybook/react-native"
3 | import { StoryScreen, Story, UseCase } from "../../../storybook/views"
4 | import { color } from "../../theme"
5 | import { Sponsors } from "./sponsors"
6 |
7 | storiesOf("Sponsors", module)
8 | .addDecorator((fn) => {fn()})
9 | .add("Style Presets", () => (
10 |
11 |
12 |
13 |
14 |
15 | ))
16 |
--------------------------------------------------------------------------------
/app/components/survey-link/survey-link.story.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { storiesOf } from "@storybook/react-native"
3 | import { StoryScreen, Story, UseCase } from "../../../storybook/views"
4 | import { color } from "../../theme"
5 | import { SurveyLink } from "./survey-link"
6 |
7 | storiesOf("SurveyLink", module)
8 | .addDecorator((fn) => {fn()})
9 | .add("Style Presets", () => (
10 |
11 |
12 |
13 |
14 |
15 | ))
16 |
--------------------------------------------------------------------------------
/app/components/survey-link/survey-link.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import { Linking } from "react-native"
3 | import { ContentLink } from "../content-link/content-link"
4 |
5 | export function SurveyLink() {
6 | const onPressLink = () => {
7 | Linking.openURL("https://www.surveymonkey.com/r/ChainReact2019")
8 | }
9 |
10 | return (
11 |
17 | )
18 | }
19 |
--------------------------------------------------------------------------------
/app/components/switch/switch.props.ts:
--------------------------------------------------------------------------------
1 | import { StyleProp, ViewStyle } from "react-native"
2 |
3 | export interface SwitchProps {
4 | /**
5 | * On or off.
6 | */
7 | value?: boolean
8 | /**
9 | * Fires when the on/off switch triggers.
10 | *
11 | * @param newValue The new value we're switching to.
12 | */
13 | onToggle?: (newValue: boolean) => void
14 |
15 | /**
16 | * A style override to apply to the container. Useful for margins and paddings.
17 | */
18 | style?: StyleProp
19 |
20 | /**
21 | * Additional track styling when on.
22 | */
23 | trackOnStyle?: StyleProp
24 |
25 | /**
26 | * Additional track styling when off.
27 | */
28 | trackOffStyle?: StyleProp
29 |
30 | /**
31 | * Additional thumb styling when on.
32 | */
33 | thumbOnStyle?: StyleProp
34 |
35 | /**
36 | * Additional thumb styling when off.
37 | */
38 | thumbOffStyle?: StyleProp
39 | }
40 |
--------------------------------------------------------------------------------
/app/components/tab-icon/icons/calendar.active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/tab-icon/icons/calendar.active.png
--------------------------------------------------------------------------------
/app/components/tab-icon/icons/calendar.active@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/tab-icon/icons/calendar.active@2x.png
--------------------------------------------------------------------------------
/app/components/tab-icon/icons/calendar.active@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/tab-icon/icons/calendar.active@3x.png
--------------------------------------------------------------------------------
/app/components/tab-icon/icons/calendar.inactive.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/tab-icon/icons/calendar.inactive.png
--------------------------------------------------------------------------------
/app/components/tab-icon/icons/calendar.inactive@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/tab-icon/icons/calendar.inactive@2x.png
--------------------------------------------------------------------------------
/app/components/tab-icon/icons/calendar.inactive@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/tab-icon/icons/calendar.inactive@3x.png
--------------------------------------------------------------------------------
/app/components/tab-icon/icons/info.active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/tab-icon/icons/info.active.png
--------------------------------------------------------------------------------
/app/components/tab-icon/icons/info.active@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/tab-icon/icons/info.active@2x.png
--------------------------------------------------------------------------------
/app/components/tab-icon/icons/info.active@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/tab-icon/icons/info.active@3x.png
--------------------------------------------------------------------------------
/app/components/tab-icon/icons/info.inactive.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/tab-icon/icons/info.inactive.png
--------------------------------------------------------------------------------
/app/components/tab-icon/icons/info.inactive@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/tab-icon/icons/info.inactive@2x.png
--------------------------------------------------------------------------------
/app/components/tab-icon/icons/info.inactive@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/tab-icon/icons/info.inactive@3x.png
--------------------------------------------------------------------------------
/app/components/tab-icon/icons/map.active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/tab-icon/icons/map.active.png
--------------------------------------------------------------------------------
/app/components/tab-icon/icons/map.active@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/tab-icon/icons/map.active@2x.png
--------------------------------------------------------------------------------
/app/components/tab-icon/icons/map.active@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/tab-icon/icons/map.active@3x.png
--------------------------------------------------------------------------------
/app/components/tab-icon/icons/map.inactive.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/tab-icon/icons/map.inactive.png
--------------------------------------------------------------------------------
/app/components/tab-icon/icons/map.inactive@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/tab-icon/icons/map.inactive@2x.png
--------------------------------------------------------------------------------
/app/components/tab-icon/icons/map.inactive@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/tab-icon/icons/map.inactive@3x.png
--------------------------------------------------------------------------------
/app/components/tab-icon/icons/profile.active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/tab-icon/icons/profile.active.png
--------------------------------------------------------------------------------
/app/components/tab-icon/icons/profile.active@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/tab-icon/icons/profile.active@2x.png
--------------------------------------------------------------------------------
/app/components/tab-icon/icons/profile.active@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/tab-icon/icons/profile.active@3x.png
--------------------------------------------------------------------------------
/app/components/tab-icon/icons/profile.inactive.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/tab-icon/icons/profile.inactive.png
--------------------------------------------------------------------------------
/app/components/tab-icon/icons/profile.inactive@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/tab-icon/icons/profile.inactive@2x.png
--------------------------------------------------------------------------------
/app/components/tab-icon/icons/profile.inactive@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/tab-icon/icons/profile.inactive@3x.png
--------------------------------------------------------------------------------
/app/components/tab-icon/tab-icon.story.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { storiesOf } from "@storybook/react-native"
3 | import { StoryScreen, Story, UseCase } from "../../../storybook/views"
4 | import { TabIcon } from "./tab-icon"
5 |
6 | storiesOf("TabIcon", module)
7 | .addDecorator((fn) => {fn()})
8 | .add("Style Presets", () => (
9 |
10 |
11 |
12 |
13 |
14 | ))
15 |
--------------------------------------------------------------------------------
/app/components/tab-icon/tab-icon.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { Image, ImageStyle } from "react-native"
3 |
4 | const ICON: ImageStyle = {
5 | position: "absolute",
6 | alignItems: "center",
7 | justifyContent: "center",
8 | maxHeight: 24,
9 | maxWidth: 24,
10 | }
11 |
12 | const TAB_ICONS = {
13 | schedule: require("./icons/calendar.inactive.png"),
14 | scheduleActive: require("./icons/calendar.active.png"),
15 | venue: require("./icons/map.inactive.png"),
16 | venueActive: require("./icons/map.active.png"),
17 | info: require("./icons/info.inactive.png"),
18 | infoActive: require("./icons/info.active.png"),
19 | profile: require("./icons/profile.inactive.png"),
20 | profileActive: require("./icons/profile.active.png"),
21 | }
22 |
23 | interface Props {
24 | focused?: boolean
25 | routeName: keyof typeof TAB_ICONS
26 | }
27 |
28 | export const TabIcon = ({ routeName, focused }: Props) => {
29 | const tabName = focused ? `${routeName}Active` : routeName
30 |
31 | return
32 | }
33 |
--------------------------------------------------------------------------------
/app/components/text/text.props.ts:
--------------------------------------------------------------------------------
1 | import { StyleProp, TextProps as TextProperties, TextStyle } from "react-native"
2 | import i18n from "i18n-js"
3 | import { TextPresets } from "./text.presets"
4 | import { TxKeyPath } from "../../i18n"
5 |
6 | export interface TextProps extends TextProperties {
7 | /**
8 | * Children components.
9 | */
10 | children?: React.ReactNode
11 |
12 | /**
13 | * Text which is looked up via i18n.
14 | */
15 | tx?: TxKeyPath
16 |
17 | /**
18 | * Optional options to pass to i18n. Useful for interpolation
19 | * as well as explicitly setting locale or translation fallbacks.
20 | */
21 | txOptions?: i18n.TranslateOptions
22 |
23 | /**
24 | * The text to display if not using `tx` or nested components.
25 | */
26 | text?: string
27 |
28 | /**
29 | * An optional style override useful for padding & margin.
30 | */
31 | style?: StyleProp
32 |
33 | /**
34 | * One of the different types of text presets.
35 | */
36 | preset?: TextPresets
37 | }
38 |
--------------------------------------------------------------------------------
/app/components/text/text.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { Text as ReactNativeText } from "react-native"
3 | import { presets } from "./text.presets"
4 | import { TextProps } from "./text.props"
5 | import { translate } from "../../i18n"
6 |
7 | /**
8 | * For your text displaying needs.
9 | *
10 | * This component is a HOC over the built-in React Native one.
11 | */
12 | export function Text(props: TextProps) {
13 | // grab the props
14 | const { preset = "default", tx, txOptions, text, children, style: styleOverride, ...rest } = props
15 |
16 | // figure out which content to use
17 | const i18nText = tx && translate(tx, txOptions)
18 | const content = i18nText || text || children
19 |
20 | const style = presets[preset] || presets.default
21 | const styles = [style, styleOverride]
22 |
23 | return (
24 |
25 | {content}
26 |
27 | )
28 | }
29 |
--------------------------------------------------------------------------------
/app/components/title-bar/icon.back-arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/title-bar/icon.back-arrow.png
--------------------------------------------------------------------------------
/app/components/title-bar/icon.back-arrow@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/title-bar/icon.back-arrow@2x.png
--------------------------------------------------------------------------------
/app/components/title-bar/icon.back-arrow@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/title-bar/icon.back-arrow@3x.png
--------------------------------------------------------------------------------
/app/components/title-bar/title-bar.story.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { storiesOf } from "@storybook/react-native"
3 | import { StoryScreen, Story, UseCase } from "../../../storybook/views"
4 | import { TitleBar } from "./title-bar"
5 |
6 | storiesOf("TitleBar", module)
7 | .addDecorator((fn) => {fn()})
8 | .add("Style Presets", () => (
9 |
10 |
11 |
12 |
13 |
14 | ))
15 |
--------------------------------------------------------------------------------
/app/components/title-bar/title-bar.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { View, ViewStyle, Image, TextStyle, ImageStyle } from "react-native"
3 | import { Text } from "../text/text"
4 | import { palette, spacing } from "../../theme"
5 |
6 | const ROOT: ViewStyle = {
7 | flexDirection: "row",
8 | backgroundColor: palette.portGore,
9 | padding: spacing.large + spacing.tiny,
10 | }
11 |
12 | const BACK_BUTTON: ImageStyle = {
13 | width: 15,
14 | height: 15,
15 | }
16 |
17 | const TITLE: TextStyle = {}
18 |
19 | export type TitleBarProps = {
20 | title: string
21 | }
22 |
23 | export function TitleBar(props: TitleBarProps) {
24 | return (
25 |
26 |
27 |
28 |
29 | )
30 | }
31 |
--------------------------------------------------------------------------------
/app/components/travel-option/Car.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/travel-option/Car.png
--------------------------------------------------------------------------------
/app/components/travel-option/Car@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/travel-option/Car@2x.png
--------------------------------------------------------------------------------
/app/components/travel-option/Car@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/travel-option/Car@3x.png
--------------------------------------------------------------------------------
/app/components/travel-option/Lightrail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/travel-option/Lightrail.png
--------------------------------------------------------------------------------
/app/components/travel-option/Lightrail@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/travel-option/Lightrail@2x.png
--------------------------------------------------------------------------------
/app/components/travel-option/Lightrail@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/travel-option/Lightrail@3x.png
--------------------------------------------------------------------------------
/app/components/travel-option/travel-option.presets.ts:
--------------------------------------------------------------------------------
1 | export const presets = {
2 | rideShare: require("./Car.png"),
3 | massTransit: require("./Lightrail.png"),
4 | }
5 |
6 | export type TravelOptionPresets = keyof typeof presets
7 |
--------------------------------------------------------------------------------
/app/components/travel-option/travel-option.props.ts:
--------------------------------------------------------------------------------
1 | import { TextProperties } from "react-native"
2 | import { TravelOptionPresets } from "./travel-option.presets"
3 |
4 | export interface TravelOptionProps extends TextProperties {
5 | preset?: TravelOptionPresets
6 | }
7 |
--------------------------------------------------------------------------------
/app/components/travel-option/travel-option.story.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { storiesOf } from "@storybook/react-native"
3 | import { StoryScreen, Story, UseCase } from "../../../storybook/views"
4 | import { color } from "../../theme"
5 | import { TravelOption } from "./travel-option"
6 |
7 | storiesOf("TravelOption", module)
8 | .addDecorator((fn) => {fn()})
9 | .add("Style Presets", () => (
10 |
11 |
12 |
13 |
14 |
15 | ))
16 |
--------------------------------------------------------------------------------
/app/components/travel-option/travel-option.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { Image, TextProps, TextStyle, View, ViewStyle } from "react-native"
3 | import { Text } from "../text/text"
4 | import { spacing } from "../../theme"
5 |
6 | const ROOT: ViewStyle = {
7 | marginTop: spacing.extraLarge,
8 | flexDirection: "row",
9 | }
10 |
11 | const TEXT: TextStyle = {
12 | marginLeft: spacing.large,
13 | paddingVertical: spacing.tiny,
14 | }
15 |
16 | const presets = {
17 | rideShare: require("./Car.png"),
18 | massTransit: require("./Lightrail.png"),
19 | }
20 |
21 | type TravelOptionPresets = keyof typeof presets
22 | interface TravelOptionProps extends TextProps {
23 | preset?: TravelOptionPresets
24 | }
25 |
26 | export const TravelOption = (props: TravelOptionProps) => {
27 | const { preset } = props
28 | return (
29 |
30 |
31 |
36 |
37 | )
38 | }
39 |
--------------------------------------------------------------------------------
/app/components/wallpaper/bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/wallpaper/bg.png
--------------------------------------------------------------------------------
/app/components/wallpaper/bg@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/components/wallpaper/bg@2x.png
--------------------------------------------------------------------------------
/app/components/wallpaper/wallpaper.presets.ts:
--------------------------------------------------------------------------------
1 | import { ImageStyle } from "react-native"
2 |
3 | /**
4 | * All wallpaper will start off looking like this.
5 | */
6 | const BASE: ImageStyle = {
7 | position: "absolute",
8 | top: 0,
9 | left: 0,
10 | bottom: 0,
11 | right: 0,
12 | }
13 |
14 | /**
15 | * All the variations of wallpaper styling within the app.
16 | *
17 | * You want to customize these to whatever you need in your app.
18 | */
19 | export const presets = {
20 | /**
21 | * The default wallpaper styles.
22 | */
23 | stretch: {
24 | ...BASE,
25 | resizeMode: "stretch",
26 | width: null, // Have to set these to null because android ¯\_(ツ)_/¯
27 | height: null,
28 | } as ImageStyle,
29 | }
30 |
31 | /**
32 | * A list of preset names.
33 | */
34 | export type WallpaperPresets = keyof typeof presets
35 |
--------------------------------------------------------------------------------
/app/components/wallpaper/wallpaper.props.ts:
--------------------------------------------------------------------------------
1 | import { ImageStyle, StyleProp } from "react-native"
2 | import { WallpaperPresets } from "./wallpaper.presets"
3 |
4 | export interface WallpaperProps {
5 | /**
6 | * An optional style override useful for padding & margin.
7 | */
8 | style?: StyleProp
9 |
10 | /**
11 | * An optional background image to override the default image.
12 | */
13 | backgroundImage?: string
14 |
15 | /**
16 | * One of the different types of wallpaper presets.
17 | */
18 | preset?: WallpaperPresets
19 | }
20 |
--------------------------------------------------------------------------------
/app/components/wallpaper/wallpaper.story.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { storiesOf } from "@storybook/react-native"
3 | import { StoryScreen, Story, UseCase } from "../../../storybook/views"
4 | import { Wallpaper } from "./wallpaper"
5 |
6 | declare let module
7 |
8 | storiesOf("Wallpaper", module)
9 | .addDecorator((fn) => {fn()})
10 | .add("Style Presets", () => (
11 |
12 |
13 |
14 |
15 |
16 | ))
17 |
--------------------------------------------------------------------------------
/app/components/wallpaper/wallpaper.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { AutoImage as Image } from "../auto-image/auto-image"
3 | import { presets } from "./wallpaper.presets"
4 | import { WallpaperProps } from "./wallpaper.props"
5 |
6 | const defaultImage = require("./bg.png")
7 |
8 | /**
9 | * For your text displaying needs.
10 | *
11 | * This component is a HOC over the built-in React Native one.
12 | */
13 | export function Wallpaper(props: WallpaperProps) {
14 | // grab the props
15 | const { preset = "stretch", style: styleOverride, backgroundImage } = props
16 |
17 | // assemble the style
18 | const presetToUse = presets[preset] || presets.stretch
19 | const styles = [presetToUse, styleOverride]
20 |
21 | // figure out which image to use
22 | const source = backgroundImage || defaultImage
23 |
24 | return
25 | }
26 |
--------------------------------------------------------------------------------
/app/components/wi-fi/wi-fi.story.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { storiesOf } from "@storybook/react-native"
3 | import { StoryScreen, Story, UseCase } from "../../../storybook/views"
4 | import { color } from "../../theme"
5 | import { WiFi } from "./wi-fi"
6 |
7 | storiesOf("WiFi", module)
8 | .addDecorator((fn) => {fn()})
9 | .add("Style Presets", () => (
10 |
11 |
12 |
13 |
14 |
15 | ))
16 |
--------------------------------------------------------------------------------
/app/components/wi-fi/wi-fi.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { Image, ImageStyle, TextStyle, View, ViewStyle } from "react-native"
3 | import { Text } from "../text/text"
4 | import { palette, spacing } from "../../theme"
5 |
6 | const ROOT: ViewStyle = {
7 | marginTop: spacing.large,
8 | paddingHorizontal: spacing.large,
9 | }
10 | const BODY: TextStyle = {
11 | marginTop: spacing.large,
12 | }
13 | const IMAGE: ImageStyle = {
14 | width: "60%",
15 | height: 75,
16 | resizeMode: "contain",
17 | }
18 | const INPUT_WRAPPER: ViewStyle = {
19 | flex: 1,
20 | borderBottomColor: palette.martinique,
21 | borderBottomWidth: 1,
22 | paddingTop: spacing.large,
23 | paddingBottom: 8,
24 | marginTop: 40,
25 | }
26 | const INPUT: TextStyle = {
27 | marginTop: spacing.large,
28 | }
29 | const SPLITZY: ViewStyle = {
30 | flexDirection: "row",
31 | justifyContent: "space-between",
32 | alignItems: "center",
33 | }
34 |
35 | export const WiFi = () => {
36 | return (
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | )
53 | }
54 |
--------------------------------------------------------------------------------
/app/config/env.js:
--------------------------------------------------------------------------------
1 | module.exports = __DEV__ ? require("./env.dev") : require("./env.prod")
2 |
--------------------------------------------------------------------------------
/app/i18n/i18n.ts:
--------------------------------------------------------------------------------
1 | import * as Localization from "expo-localization"
2 | import i18n from "i18n-js"
3 | import en from "./en.json"
4 | // import ja from "./ja.json"
5 |
6 | i18n.fallbacks = true
7 | // i18n.translations = { en, ja }
8 | i18n.translations = { en }
9 |
10 | i18n.locale = Localization.locale || "en"
11 |
12 | /**
13 | * Builds up valid keypaths for translations.
14 | * Update to your default locale of choice if not English.
15 | */
16 | type DefaultLocale = typeof en
17 | export type TxKeyPath = RecursiveKeyOf
18 |
19 | type RecursiveKeyOf> = {
20 | [TKey in keyof TObj & string]: TObj[TKey] extends Record
21 | ? TKey | `${TKey}.${RecursiveKeyOf}`
22 | : TKey
23 | }[keyof TObj & string]
24 |
--------------------------------------------------------------------------------
/app/i18n/index.ts:
--------------------------------------------------------------------------------
1 | import "./i18n"
2 | export * from "./i18n"
3 | export * from "./translate"
4 |
--------------------------------------------------------------------------------
/app/i18n/translate.ts:
--------------------------------------------------------------------------------
1 | import i18n from "i18n-js"
2 | import { TxKeyPath } from "./i18n"
3 |
4 | /**
5 | * Translates text.
6 | *
7 | * @param key The i18n key.
8 | */
9 | export function translate(key: TxKeyPath, options?: i18n.TranslateOptions) {
10 | return key ? i18n.t(key, options) : null
11 | }
12 |
--------------------------------------------------------------------------------
/app/models/environment.ts:
--------------------------------------------------------------------------------
1 | import { Api } from "../services/api"
2 |
3 | let ReactotronDev
4 | if (__DEV__) {
5 | const { Reactotron } = require("../services/reactotron")
6 | ReactotronDev = Reactotron
7 | }
8 |
9 | /**
10 | * The environment is a place where services and shared dependencies between
11 | * models live. They are made available to every model via dependency injection.
12 | */
13 | export class Environment {
14 | constructor() {
15 | // create each service
16 | if (__DEV__) {
17 | // dev-only services
18 | this.reactotron = new ReactotronDev()
19 | }
20 | this.api = new Api()
21 | }
22 |
23 | async setup() {
24 | // allow each service to setup
25 | if (__DEV__) {
26 | await this.reactotron.setup()
27 | }
28 | await this.api.setup()
29 | }
30 |
31 | /**
32 | * Reactotron is only available in dev.
33 | */
34 | reactotron: typeof ReactotronDev
35 |
36 | /**
37 | * Our api.
38 | */
39 | api: Api
40 | }
41 |
--------------------------------------------------------------------------------
/app/models/event-store/event-store.test.ts:
--------------------------------------------------------------------------------
1 | import { EventStoreModel } from "./event-store"
2 |
3 | test("can be created", () => {
4 | const instance = EventStoreModel.create({})
5 |
6 | expect(instance).toBeTruthy()
7 | })
8 |
--------------------------------------------------------------------------------
/app/models/event/event.ts:
--------------------------------------------------------------------------------
1 | import { Instance, SnapshotOut, types } from "mobx-state-tree"
2 | import { SpeakerModel } from "../speaker/speaker"
3 |
4 | export type EVENT_DAYS = "wednesday" | "thursday" | "friday"
5 | export const DAYS = ["wednesday", "thursday", "friday"]
6 |
7 | /**
8 | * Info for each conference talk.
9 | */
10 | export const EventModel = types
11 | .model("Event")
12 | .props({
13 | id: types.identifier,
14 | startTime: types.string,
15 | endTime: types.string,
16 | duration: types.string,
17 | day: types.enumeration(DAYS),
18 | shortTitle: types.maybeNull(types.string),
19 | title: types.maybeNull(types.string),
20 | description: types.maybeNull(types.string),
21 | image: types.maybeNull(types.string),
22 | speakers: types.array(types.reference(SpeakerModel)),
23 | menuItems: types.maybeNull(types.array(types.string)),
24 | sponsor: types.maybeNull(types.string),
25 | eventType: types.enumeration([
26 | "talk",
27 | "announcement",
28 | "meal",
29 | "workshop",
30 | "break",
31 | "panel",
32 | "afterparty",
33 | ]),
34 | location: types.maybeNull(types.string),
35 | track: types.maybeNull(types.enumeration(["BEGINNER", "INTERMEDIATE", "ADVANCED"])),
36 | prerequisites: types.maybeNull(types.array(types.string)),
37 | })
38 | .views((event) => ({
39 | get screenTitle() {
40 | return event.shortTitle || event.title
41 | },
42 | })) // eslint-disable-line @typescript-eslint/no-unused-vars
43 | .actions((self) => ({})) // eslint-disable-line @typescript-eslint/no-unused-vars
44 |
45 | type EventType = Instance
46 | export interface Event extends EventType {}
47 | type EventSnapshotType = SnapshotOut
48 | export interface EventSnapshot extends EventSnapshotType {}
49 | export const createEventDefaultModel = () => types.optional(EventModel, {})
50 |
--------------------------------------------------------------------------------
/app/models/extensions/with-environment.ts:
--------------------------------------------------------------------------------
1 | import { getEnv, IStateTreeNode } from "mobx-state-tree"
2 | import { Environment } from "../environment"
3 |
4 | /**
5 | * Adds a environment property to the node for accessing our
6 | * Environment in strongly typed.
7 | */
8 | export const withEnvironment = (self: IStateTreeNode) => ({
9 | views: {
10 | /**
11 | * The environment.
12 | */
13 | get environment() {
14 | return getEnv(self)
15 | },
16 | },
17 | })
18 |
--------------------------------------------------------------------------------
/app/models/extensions/with-root-store.ts:
--------------------------------------------------------------------------------
1 | import { getRoot, IStateTreeNode } from "mobx-state-tree"
2 | import { RootStore } from "../root-store/root-store"
3 |
4 | /**
5 | * Adds a rootStore property to the node for a convenient
6 | * and strongly typed way for stores to access other stores.
7 | */
8 | export const withRootStore = (self: IStateTreeNode) => ({
9 | views: {
10 | /**
11 | * The root store.
12 | */
13 | get rootStore(): RootStore {
14 | return getRoot(self)
15 | },
16 | },
17 | })
18 |
--------------------------------------------------------------------------------
/app/models/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./extensions/with-environment"
2 | export * from "./extensions/with-root-store"
3 | export * from "./root-store/root-store"
4 | export * from "./root-store/root-store-context"
5 | export * from "./root-store/setup-root-store"
6 | export * from "./event-store/event-store"
7 | export * from "./event/event"
8 | export * from "./setting/setting"
9 | export * from "./speaker/speaker"
10 |
--------------------------------------------------------------------------------
/app/models/root-store/root-store-context.ts:
--------------------------------------------------------------------------------
1 | import { createContext, useContext } from "react"
2 | import { RootStore } from "./root-store"
3 |
4 | /**
5 | * Create a context we can use to
6 | * - Provide access to our stores from our root component
7 | * - Consume stores in our screens (or other components, though it's
8 | * preferable to just connect screens)
9 | */
10 | const RootStoreContext = createContext({} as RootStore)
11 |
12 | /**
13 | * The provider our root component will use to expose the root store
14 | */
15 | export const RootStoreProvider = RootStoreContext.Provider
16 |
17 | /**
18 | * A hook that screens can use to gain access to our stores, with
19 | * `const { someStore, someOtherStore } = useStores()`,
20 | * or less likely: `const rootStore = useStores()`
21 | */
22 | export const useStores = (): RootStore => useContext(RootStoreContext)
23 |
--------------------------------------------------------------------------------
/app/models/root-store/root-store.ts:
--------------------------------------------------------------------------------
1 | import { Instance, SnapshotOut, types } from "mobx-state-tree"
2 | import { EventStoreModel } from "../event-store/event-store"
3 |
4 | /**
5 | * This is our primary store that holds all other stores.
6 | */
7 | export const RootStoreModel = types
8 | .model("RootStore")
9 | .props({
10 | eventStore: types.optional(
11 | types.late(() => EventStoreModel),
12 | {},
13 | ),
14 | })
15 | .actions((root) => ({
16 | async refresh() {
17 | return root.eventStore.refresh()
18 | },
19 | reset() {
20 | // Need to properly reset everything here
21 | // root.eventStore = EventStoreModel.create({})
22 | },
23 | }))
24 |
25 | /**
26 | * The RootStore instance.
27 | */
28 | export interface RootStore extends Instance {}
29 |
30 | /**
31 | * The data of a RootStore.
32 | */
33 | export interface RootStoreSnapshot extends SnapshotOut {}
34 |
--------------------------------------------------------------------------------
/app/models/setting/setting.test.ts:
--------------------------------------------------------------------------------
1 | import { SettingModel } from "./setting"
2 |
3 | test("can be created", () => {
4 | const instance = SettingModel.create({})
5 |
6 | expect(instance).toBeTruthy()
7 | })
8 |
--------------------------------------------------------------------------------
/app/models/setting/setting.ts:
--------------------------------------------------------------------------------
1 | import { Instance, SnapshotOut, types } from "mobx-state-tree"
2 |
3 | /**
4 | * Model description here for TypeScript hints.
5 | */
6 | export const SettingModel = types
7 | .model("Setting")
8 | .props({})
9 | .views((self) => ({})) // eslint-disable-line @typescript-eslint/no-unused-vars
10 | .actions((self) => ({})) // eslint-disable-line @typescript-eslint/no-unused-vars
11 |
12 | type SettingType = Instance
13 | export interface Setting extends SettingType {}
14 | type SettingSnapshotType = SnapshotOut
15 | export interface SettingSnapshot extends SettingSnapshotType {}
16 | export const createSettingDefaultModel = () => types.optional(SettingModel, {})
17 |
--------------------------------------------------------------------------------
/app/models/speaker/speaker.test.ts:
--------------------------------------------------------------------------------
1 | import { SpeakerModel } from "./speaker"
2 |
3 | test("can be created", () => {
4 | const instance = SpeakerModel.create({
5 | id: "asdfd",
6 | })
7 |
8 | expect(instance).toBeTruthy()
9 | })
10 |
--------------------------------------------------------------------------------
/app/models/speaker/speaker.ts:
--------------------------------------------------------------------------------
1 | import { Instance, SnapshotOut, types } from "mobx-state-tree"
2 |
3 | /**
4 | * Info for each speaker.
5 | */
6 | export const SpeakerModel = types
7 | .model("Speaker")
8 | .props({
9 | id: types.identifier,
10 | name: types.maybeNull(types.string),
11 | employer: types.maybeNull(types.string),
12 | image: types.maybeNull(types.string),
13 | bio: types.maybeNull(types.string),
14 | facebook: types.maybeNull(types.string),
15 | github: types.maybeNull(types.string),
16 | twitter: types.maybeNull(types.string),
17 | medium: types.maybeNull(types.string),
18 | instagram: types.maybeNull(types.string),
19 | dribbble: types.maybeNull(types.string),
20 | websites: types.maybeNull(types.array(types.string)),
21 | })
22 | .views((speaker) => ({})) // eslint-disable-line @typescript-eslint/no-unused-vars
23 | .actions((speaker) => ({})) // eslint-disable-line @typescript-eslint/no-unused-vars
24 |
25 | type SpeakerType = Instance
26 | export interface Speaker extends SpeakerType {}
27 | type SpeakerSnapshotType = SnapshotOut
28 | export interface SpeakerSnapshot extends SpeakerSnapshotType {}
29 | export const createSpeakerDefaultModel = () => types.optional(SpeakerModel, {})
30 |
--------------------------------------------------------------------------------
/app/navigators/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./app-navigator"
2 | export * from "./navigation-utilities"
3 | // export other navigators from here
4 |
--------------------------------------------------------------------------------
/app/screens/code-of-conduct/code-of-conduct-screen.tsx:
--------------------------------------------------------------------------------
1 | import { useNavigation } from "@react-navigation/core"
2 | import React, { useLayoutEffect } from "react"
3 | import { TextStyle, ViewStyle } from "react-native"
4 | // import { BackButton } from "../../components/back-button"
5 | import { Contact } from "../../components/contact/contact"
6 | import { Screen } from "../../components/screen/screen"
7 | import { Text } from "../../components/text/text"
8 | import { color, spacing } from "../../theme"
9 | import { palette } from "../../theme/palette"
10 |
11 | const ROOT: ViewStyle = {
12 | marginHorizontal: spacing.large,
13 | paddingBottom: spacing.huge,
14 | }
15 |
16 | const TITLE: TextStyle = {
17 | marginTop: spacing.extraLarge,
18 | letterSpacing: 1.68,
19 | }
20 |
21 | const SECTION: TextStyle = {
22 | marginVertical: spacing.medium,
23 | }
24 |
25 | const SECTION_TITLE: TextStyle = {
26 | fontWeight: "500",
27 | letterSpacing: 3.0,
28 | fontSize: 14,
29 | color: color.palette.shamrock,
30 | marginTop: spacing.medium,
31 | }
32 |
33 | const email = "conf@infinite.red"
34 | const twitter = "chainreactconf"
35 | const phoneNumber = "(360) 450-4752"
36 |
37 | export const CodeOfConductScreen = () => {
38 | const navigation = useNavigation()
39 |
40 | useLayoutEffect(() => {
41 | navigation.setOptions({ title: "Code of Conduct" })
42 | }, [navigation])
43 |
44 | return (
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 | )
55 | }
56 |
--------------------------------------------------------------------------------
/app/screens/event-details/image-dimension-helpers.ts:
--------------------------------------------------------------------------------
1 | import { spacing } from "../../theme"
2 | const IMAGE_ASPECT_RATIO = 1.5
3 |
4 | export const calculateImageDimensions = (screenWidth) => {
5 | const imageWidth = 0.92 * (screenWidth - 2 * spacing.large) // 92% of the available container, screen width minus twice the screen padding.
6 | const imageHeight = imageWidth / IMAGE_ASPECT_RATIO
7 | return {
8 | height: imageHeight,
9 | width: imageWidth,
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/app/screens/event-details/images/bumped.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/screens/event-details/images/bumped.png
--------------------------------------------------------------------------------
/app/screens/event-details/images/img.afterparty-g2i.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/screens/event-details/images/img.afterparty-g2i.png
--------------------------------------------------------------------------------
/app/screens/event-details/images/img.afterparty-squarespace.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/screens/event-details/images/img.afterparty-squarespace.png
--------------------------------------------------------------------------------
/app/screens/event-details/images/img.break.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/screens/event-details/images/img.break.png
--------------------------------------------------------------------------------
/app/screens/event-details/images/img.event.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/screens/event-details/images/img.event.png
--------------------------------------------------------------------------------
/app/screens/event-details/images/img.event@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/screens/event-details/images/img.event@2x.png
--------------------------------------------------------------------------------
/app/screens/event-details/images/img.event@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/screens/event-details/images/img.event@3x.png
--------------------------------------------------------------------------------
/app/screens/event-details/images/img.partylogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/screens/event-details/images/img.partylogo.png
--------------------------------------------------------------------------------
/app/screens/event-details/images/img.partylogo@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/screens/event-details/images/img.partylogo@2x.png
--------------------------------------------------------------------------------
/app/screens/event-details/images/img.partylogo@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/screens/event-details/images/img.partylogo@3x.png
--------------------------------------------------------------------------------
/app/screens/event-details/images/sponsor-bumped-thumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/screens/event-details/images/sponsor-bumped-thumb.png
--------------------------------------------------------------------------------
/app/screens/event-details/images/sponsor-bumped.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/screens/event-details/images/sponsor-bumped.png
--------------------------------------------------------------------------------
/app/screens/event-details/render-after-party.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { Image, ImageStyle, TextStyle, View, ViewStyle } from "react-native"
3 | import { Text } from "../../components"
4 | import { Event } from "../../models"
5 | import { getScreenWidth, palette, spacing } from "../../theme"
6 | import { calculateImageDimensions } from "./image-dimension-helpers"
7 |
8 | const FULL_SIZE: ViewStyle = {
9 | width: "100%",
10 | height: "100%",
11 | }
12 |
13 | const FULL_WIDTH_IMAGE: ImageStyle = {
14 | resizeMode: "contain",
15 | }
16 |
17 | const TITLE: TextStyle = {
18 | fontSize: 20,
19 | color: palette.white,
20 | marginTop: spacing.large,
21 | }
22 |
23 | const AFTER_PARTY_DESCRIPTION: TextStyle = { marginTop: spacing.small }
24 |
25 | type RenderAfterPartyProps = { event: Event }
26 | export const RenderAfterParty = (props: RenderAfterPartyProps) => {
27 | const { title, description, sponsor, location } = props.event
28 | const imageDimensions = calculateImageDimensions(getScreenWidth())
29 |
30 | let image = null
31 | switch (sponsor) {
32 | case "Squarespace":
33 | image = require("./images/img.afterparty-squarespace.png")
34 | break
35 | case "Bumped":
36 | image = require("./images/bumped.png")
37 | break
38 | case "G2i":
39 | image = require("./images/img.afterparty-g2i.png")
40 | break
41 | default:
42 | image = require("./images/img.afterparty-g2i.png")
43 | break
44 | }
45 |
46 | return (
47 |
48 |
49 |
50 |
51 |
52 |
53 | {location && (
54 |
59 | )}
60 | {location && }
61 |
62 | )
63 | }
64 |
--------------------------------------------------------------------------------
/app/screens/event-details/render-announcement.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { TextStyle, View, ViewStyle } from "react-native"
3 | import { SpeakerBio, SpeakerImage, Text } from "../../components"
4 | import { Event } from "../../models"
5 | import { spacing, textSizes } from "../../theme"
6 |
7 | const FULL_SIZE: ViewStyle = {
8 | width: "100%",
9 | height: "100%",
10 | }
11 |
12 | const PANEL_BIO: ViewStyle = {
13 | flex: 1,
14 | marginTop: spacing.extraLarge + spacing.large,
15 | }
16 |
17 | const TITLE: TextStyle = {
18 | fontSize: textSizes.title,
19 | }
20 |
21 | const DESCRIPTION: TextStyle = {
22 | marginTop: spacing.large + spacing.tiny + spacing.tiny,
23 | }
24 |
25 | type RenderAnnouncementProps = { event: Event }
26 | export const RenderAnnouncement = (props: RenderAnnouncementProps) => {
27 | const { title, description, speakers } = props.event
28 | return (
29 |
30 |
31 |
32 | {speakers &&
33 | speakers.length &&
34 | speakers.map((speaker, index) => {
35 | const isLast = index === speakers.length - 1
36 | return (
37 |
38 |
39 |
40 |
41 | )
42 | })}
43 |
44 | )
45 | }
46 |
--------------------------------------------------------------------------------
/app/screens/event-details/render-default-event.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { TextStyle, View, ViewStyle } from "react-native"
3 | import { Text } from "../../components"
4 | import { Event } from "../../models"
5 | import { palette, spacing, textSizes } from "../../theme"
6 |
7 | const FULL_SIZE: ViewStyle = {
8 | width: "100%",
9 | height: "100%",
10 | }
11 |
12 | const LABEL: TextStyle = {
13 | marginTop: spacing.extraLarge + spacing.large,
14 | color: palette.shamrock,
15 | marginBottom: spacing.large,
16 | }
17 |
18 | const TITLE: TextStyle = {
19 | fontSize: textSizes.title,
20 | }
21 |
22 | type RenderDefaultEventProps = { event: Event }
23 |
24 | export function RenderDefaultEvent({ event }: RenderDefaultEventProps) {
25 | const { title, description } = event
26 | return (
27 |
28 | {/*
29 |
30 | */}
31 |
32 |
33 |
34 |
35 | )
36 | }
37 |
--------------------------------------------------------------------------------
/app/screens/event-details/render-event-type.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { Event } from "../../models"
3 | import { RenderBreak } from "./render-break"
4 | import { RenderTalk } from "./render-talk"
5 | import { RenderAnnouncement } from "./render-announcement"
6 | import { RenderWorkshop } from "./render-workshop"
7 | import { RenderMeal } from "./render-meal"
8 | import { RenderAfterParty } from "./render-after-party"
9 | import { RenderPanel } from "./render-panel"
10 | import { RenderDefaultEvent } from "./render-default-event"
11 |
12 | type RenderEventTypeProps = {
13 | event: Event
14 | }
15 | export const RenderEventType = ({ event }: RenderEventTypeProps) => {
16 | switch (event.eventType.toLowerCase()) {
17 | case "talk":
18 | return
19 | case "workshop":
20 | return
21 | case "break":
22 | return
23 | case "meal":
24 | return
25 | case "panel":
26 | return
27 | case "announcement":
28 | return
29 | case "afterparty":
30 | return
31 | default:
32 | return
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/app/screens/event-details/render-panel.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { Image, ImageStyle, TextStyle, View, ViewStyle } from "react-native"
3 | import { SpeakerBio, SpeakerImage, Text } from "../../components"
4 | import { Event } from "../../models"
5 | import { getScreenWidth, palette, spacing } from "../../theme"
6 | import { calculateImageDimensions } from "./image-dimension-helpers"
7 |
8 | const FULL_SIZE: ViewStyle = {
9 | width: "100%",
10 | height: "100%",
11 | }
12 |
13 | const FULL_WIDTH_IMAGE: ImageStyle = {
14 | resizeMode: "contain",
15 | }
16 |
17 | const TITLE: TextStyle = {
18 | fontSize: 20,
19 | color: palette.white,
20 | marginTop: spacing.large,
21 | }
22 |
23 | const DESCRIPTION: TextStyle = { marginTop: spacing.large + spacing.tiny + spacing.tiny }
24 |
25 | const PANEL_BIO: ViewStyle = { flex: 1, marginTop: spacing.extraLarge + spacing.large }
26 |
27 | type RenderPanelProps = { event: Event }
28 | export const RenderPanel = (props: RenderPanelProps) => {
29 | const { image, title, description, speakers } = props.event
30 |
31 | const imageDimensions = calculateImageDimensions(getScreenWidth())
32 |
33 | return (
34 |
35 | {}
36 |
37 |
38 | {speakers &&
39 | speakers.length &&
40 | speakers.map((speaker, index) => {
41 | const isLast = index === speakers.length - 1
42 | return (
43 |
44 |
45 |
46 |
47 | )
48 | })}
49 |
50 | )
51 | }
52 |
--------------------------------------------------------------------------------
/app/screens/event-details/render-talk.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { View, ViewStyle } from "react-native"
3 | import Hyperlink from "react-native-hyperlink"
4 | import { SpeakerBio, TalkTitle, Text } from "../../components"
5 | import { SpeakerImage } from "../../components/speaker-image/speaker-image"
6 | import { Event } from "../../models"
7 | import { palette, spacing } from "../../theme"
8 |
9 | const FULL_SIZE: ViewStyle = {
10 | width: "100%",
11 | height: "100%",
12 | }
13 |
14 | type RenderTalkProps = { event: Event }
15 |
16 | export const RenderTalk = ({ event }: RenderTalkProps) => {
17 | return (
18 |
19 | {event.speakers && }
20 |
21 | {event.description && (
22 |
26 |
27 | {event.description}
28 |
29 |
30 | )}
31 | {event.speakers && }
32 |
33 | )
34 | }
35 |
--------------------------------------------------------------------------------
/app/screens/event-details/render-workshop.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { View, ViewStyle } from "react-native"
3 | import { SpeakerBio, SpeakerImage, TalkTitle } from "../../components"
4 | import { Event } from "../../models"
5 |
6 | const FULL_SIZE: ViewStyle = {
7 | width: "100%",
8 | height: "100%",
9 | }
10 |
11 | type RenderWorkshopProps = { event: Event }
12 |
13 | export function RenderWorkshop({ event }: RenderWorkshopProps) {
14 | return (
15 |
16 |
17 |
18 |
19 |
20 | )
21 | }
22 |
--------------------------------------------------------------------------------
/app/screens/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./welcome/welcome-screen"
2 | export * from "./error/error-boundary"
3 | // export other screens here
4 | export * from "./venue/venue-screen"
5 | export * from "./schedule/schedule-screen"
6 | export * from "./code-of-conduct/code-of-conduct-screen"
7 | export * from "./event-details/event-details-screen"
8 | export * from "./info/info-screen"
9 |
--------------------------------------------------------------------------------
/app/screens/info/info-screen.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useLayoutEffect } from "react"
2 | import { TextStyle } from "react-native"
3 | import { Text } from "../../components/text/text"
4 | import { Screen } from "../../components/screen/screen"
5 | import { palette, spacing } from "../../theme"
6 | import { PresentedBy } from "../../components/presented-by/presented-by"
7 | import { WiFi } from "../../components/wi-fi/wi-fi"
8 | import { Conduct } from "../../components/conduct/conduct"
9 | import { Sponsors } from "../../components/sponsors/sponsors"
10 | import { SurveyLink } from "../../components/survey-link/survey-link"
11 | import { useNavigation } from "@react-navigation/core"
12 |
13 | const TITLE: TextStyle = {
14 | marginTop: spacing.extraLarge,
15 | marginLeft: spacing.large,
16 | }
17 |
18 | export const InfoScreen = () => {
19 | const [renderFullContent, setRenderFullContent] = useState(false)
20 | const navigation = useNavigation()
21 |
22 | useLayoutEffect(() => {
23 | requestAnimationFrame(() => {
24 | setRenderFullContent(true)
25 | })
26 |
27 | navigation.setOptions({ title: "Info" })
28 | }, [navigation])
29 |
30 | return (
31 |
32 |
33 |
34 | navigation.navigate("infoCodeOfConduct")} />
35 |
36 | {renderFullContent ? : null}
37 |
38 |
39 | )
40 | }
41 |
--------------------------------------------------------------------------------
/app/screens/schedule/render-event.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { useNavigation } from "@react-navigation/core"
3 | import { ScheduleCell } from "../../components"
4 | import { ScheduleCellPresetNames } from "../../components/schedule-cell/schedule-cell.presets"
5 | import { Event, useStores } from "../../models"
6 | import { observer } from "mobx-react-lite"
7 |
8 | type RenderEventProps = { event: Event; index: number }
9 | export const RenderEvent = observer(({ event, index }: RenderEventProps) => {
10 | const navigation = useNavigation()
11 | const { eventStore } = useStores()
12 |
13 | const eventType = event.eventType.toLowerCase()
14 | const cellPreset: ScheduleCellPresetNames =
15 | eventType === "break" || eventType === "afterparty" ? eventType : "default"
16 |
17 | return (
18 | {
23 | eventStore.setCurrentEvent(event)
24 | navigation.navigate("eventDetails")
25 | }}
26 | key={index}
27 | />
28 | )
29 | })
30 |
--------------------------------------------------------------------------------
/app/screens/schedule/schedule-content.tsx:
--------------------------------------------------------------------------------
1 | import { observer } from "mobx-react-lite"
2 | import React from "react"
3 | import { TextStyle, View } from "react-native"
4 | import { Text } from "../../components"
5 | import { EventStore, EVENT_DAYS } from "../../models"
6 | import { color, spacing } from "../../theme"
7 | import { RenderEvent } from "./render-event"
8 |
9 | const SUBTITLE: TextStyle = {
10 | color: color.palette.white,
11 | fontWeight: "600",
12 | paddingHorizontal: spacing.large,
13 | marginTop: spacing.small,
14 | }
15 | const DATE: TextStyle = {
16 | fontStyle: "italic",
17 | fontWeight: "400",
18 | paddingHorizontal: spacing.large,
19 | marginBottom: spacing.small + spacing.large,
20 | }
21 |
22 | type ScheduleContentProps = {
23 | eventStore: EventStore
24 | selected: EVENT_DAYS
25 | }
26 | export const ScheduleContent = observer(({ eventStore, selected }: ScheduleContentProps) => {
27 | const selectedEvents = eventStore.eventsForDay(selected || "wednesday")
28 |
29 | return (
30 |
31 |
40 |
49 | {selectedEvents &&
50 | selectedEvents.map((event, index) => (
51 |
52 | ))}
53 |
54 | )
55 | })
56 |
--------------------------------------------------------------------------------
/app/screens/schedule/schedule-workshops.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { useNavigation } from "@react-navigation/core"
3 | import { TextStyle, View } from "react-native"
4 | import { ScheduleCell, Text } from "../../components"
5 | import { color, spacing } from "../../theme"
6 | import { Event, useStores } from "../../models"
7 | import { observer } from "mobx-react-lite"
8 |
9 | const SUBTITLE: TextStyle = {
10 | color: color.palette.white,
11 | fontWeight: "600",
12 | paddingHorizontal: spacing.large,
13 | marginTop: spacing.small,
14 | }
15 | const DATE: TextStyle = {
16 | fontStyle: "italic",
17 | fontWeight: "400",
18 | paddingHorizontal: spacing.large,
19 | marginBottom: spacing.small + spacing.large,
20 | }
21 |
22 | export const ScheduleWorkshops = observer(() => {
23 | const { eventStore } = useStores()
24 | const navigation = useNavigation()
25 |
26 | const { events } = eventStore
27 | const beginnerWorkshop = events.find((event) => event.track === "BEGINNER")
28 | const intermediateWorkshop = events.find((event) => event.track === "INTERMEDIATE")
29 | const advancedWorkshop = events.find((event) => event.track === "ADVANCED")
30 | const welcomeParty = events.find((event) => event.eventType === "afterparty")
31 | const onPressWorkshop = (event: Event) => {
32 | eventStore.setCurrentEvent(event)
33 | navigation.navigate("eventDetails")
34 | }
35 |
36 | return (
37 |
38 |
39 |
40 |
41 |
42 |
43 |
49 |
50 | )
51 | })
52 |
--------------------------------------------------------------------------------
/app/screens/welcome/bg.welcome.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/screens/welcome/bg.welcome.png
--------------------------------------------------------------------------------
/app/screens/welcome/bg.welcome@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/screens/welcome/bg.welcome@2x.png
--------------------------------------------------------------------------------
/app/screens/welcome/bg.welcome@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/app/screens/welcome/bg.welcome@3x.png
--------------------------------------------------------------------------------
/app/screens/welcome/welcome-screen.tsx:
--------------------------------------------------------------------------------
1 | import React, { FC } from "react"
2 | import { View, ViewStyle, TextStyle } from "react-native"
3 | import { StackScreenProps } from "@react-navigation/stack"
4 | import { observer } from "mobx-react-lite"
5 | import { Button, Footer, Screen, Text } from "../../components"
6 | import { spacing, palette } from "../../theme"
7 | import { NavigatorParamList } from "../../navigators"
8 |
9 | const backgroundImage = require("./bg.welcome.png")
10 |
11 | const ROOT: ViewStyle = { justifyContent: "space-between" }
12 | const TOP_CONTAINER: ViewStyle = {
13 | marginTop: spacing.large,
14 | }
15 | const HEADER1: TextStyle = {
16 | paddingHorizontal: spacing.large,
17 | marginTop: spacing.large,
18 | color: palette.white,
19 | }
20 | const HEADER2: TextStyle = {
21 | marginBottom: 38,
22 | paddingHorizontal: spacing.large,
23 | color: palette.offWhite,
24 | }
25 | const SUBHEADER: TextStyle = {
26 | paddingHorizontal: spacing.large,
27 | color: palette.offWhite,
28 | }
29 |
30 | export const WelcomeScreen: FC> = observer(
31 | ({ navigation }) => {
32 | const nextScreen = () => navigation.navigate("tabs")
33 |
34 | return (
35 |
41 |
42 |
43 |
44 |
45 |
46 |
55 |
56 | )
57 | },
58 | )
59 |
--------------------------------------------------------------------------------
/app/services/api/api-config.ts:
--------------------------------------------------------------------------------
1 | // Use this import if you want to use "env.js" file
2 | // const { API_URL } = require("../../config/env")
3 | // Or just specify it directly like this:
4 | const API_URL = "http://example.com"
5 |
6 | /**
7 | * The options used to configure the API.
8 | */
9 | export interface ApiConfig {
10 | /**
11 | * The URL of the api.
12 | */
13 | url: string
14 |
15 | /**
16 | * Milliseconds before we timeout the request.
17 | */
18 | timeout: number
19 | }
20 |
21 | /**
22 | * The default configuration for the app.
23 | */
24 | export const DEFAULT_API_CONFIG: ApiConfig = {
25 | url: API_URL || "https://jsonplaceholder.typicode.com",
26 | timeout: 10000,
27 | }
28 |
--------------------------------------------------------------------------------
/app/services/api/api.types.ts:
--------------------------------------------------------------------------------
1 | import { GeneralApiProblem } from "./api-problem"
2 | // import { Character } from "../../models/character/character"
3 |
4 | export interface User {
5 | id: number
6 | name: string
7 | }
8 |
9 | export type GetUsersResult = { kind: "ok"; users: User[] } | GeneralApiProblem
10 | export type GetUserResult = { kind: "ok"; user: User } | GeneralApiProblem
11 |
12 | export type GetCharactersResult =
13 | | { kind: "ok"; characters: /* Character */ unknown[] }
14 | | GeneralApiProblem
15 | export type GetCharacterResult =
16 | | { kind: "ok"; character: /* Character */ unknown }
17 | | GeneralApiProblem
18 |
--------------------------------------------------------------------------------
/app/services/api/character-api.ts:
--------------------------------------------------------------------------------
1 | import { ApiResponse } from "apisauce"
2 | import { Api } from "./api"
3 | import { GetCharactersResult } from "./api.types"
4 | import { getGeneralApiProblem } from "./api-problem"
5 |
6 | const API_PAGE_SIZE = 50
7 |
8 | export class CharacterApi {
9 | private api: Api
10 |
11 | constructor(api: Api) {
12 | this.api = api
13 | }
14 |
15 | async getCharacters(): Promise {
16 | try {
17 | // make the api call
18 | const response: ApiResponse = await this.api.apisauce.get(
19 | "https://raw.githubusercontent.com/infinitered/ignite/master/data/rick-and-morty.json",
20 | { amount: API_PAGE_SIZE },
21 | )
22 |
23 | // the typical ways to die when calling an api
24 | if (!response.ok) {
25 | const problem = getGeneralApiProblem(response)
26 | if (problem) return problem
27 | }
28 |
29 | const characters = response.data.results
30 |
31 | return { kind: "ok", characters }
32 | } catch (e) {
33 | __DEV__ && console.tron.log(e.message)
34 | return { kind: "bad-data" }
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/services/api/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./api"
2 | export * from "./api.types"
3 |
--------------------------------------------------------------------------------
/app/services/reactotron/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./reactotron"
2 |
--------------------------------------------------------------------------------
/app/services/reactotron/reactotron-config.ts:
--------------------------------------------------------------------------------
1 | export interface ReactotronConfig {
2 | /** The name of the app. */
3 | name?: string
4 | /** The host to connect to: default 'localhost'. */
5 | host?: string
6 | /** Should we use async storage */
7 | useAsyncStorage?: boolean
8 | /** Should we clear Reactotron when load? */
9 | clearOnLoad?: boolean
10 | /** Root state logging. */
11 | state?: {
12 | /** log the initial data that we put into the state on startup? */
13 | initial?: boolean
14 | /** log snapshot changes. */
15 | snapshots?: boolean
16 | }
17 | }
18 |
19 | /**
20 | * The default Reactotron configuration.
21 | */
22 | export const DEFAULT_REACTOTRON_CONFIG: ReactotronConfig = {
23 | clearOnLoad: true,
24 | host: "localhost",
25 | useAsyncStorage: true,
26 | state: {
27 | initial: true,
28 | snapshots: false,
29 | },
30 | }
31 |
--------------------------------------------------------------------------------
/app/services/reactotron/tron.ts:
--------------------------------------------------------------------------------
1 | import Reactotron from "reactotron-react-native"
2 | export const Tron = Reactotron
3 |
--------------------------------------------------------------------------------
/app/services/reactotron/tron.web.ts:
--------------------------------------------------------------------------------
1 | import Reactotron from "reactotron-react-js"
2 | export const Tron = Reactotron
3 |
--------------------------------------------------------------------------------
/app/theme/color.ts:
--------------------------------------------------------------------------------
1 | import { palette } from "./palette"
2 |
3 | /**
4 | * Roles for colors. Prefer using these over the palette. It makes it easier
5 | * to change things.
6 | *
7 | * The only roles we need to place in here are the ones that span through the app.
8 | *
9 | * If you have a specific use-case, like a spinner color. It makes more sense to
10 | * put that in the component.
11 | */
12 | export const color = {
13 | /**
14 | * The palette is available to use, but prefer using the name.
15 | */
16 | palette,
17 | /**
18 | * A helper for making something see-thru. Use sparingly as many layers of transparency
19 | * can cause older Android devices to slow down due to the excessive compositing required
20 | * by their under-powered GPUs.
21 | */
22 | transparent: "rgba(0, 0, 0, 0)",
23 | /**
24 | * The screen background.
25 | */
26 | background: palette.portGore,
27 | /**
28 | * The main tinting color.
29 | */
30 | primary: palette.crimson,
31 | /**
32 | * The main tinting color, but darker.
33 | */
34 | primaryDarker: palette.portGore,
35 | /**
36 | * A subtle color used for borders and lines.
37 | */
38 | line: palette.offWhite,
39 | /**
40 | * The default color of text in many components.
41 | */
42 | text: palette.white,
43 | /**
44 | * Secondard information.
45 | */
46 | dim: palette.lightGrey,
47 | /**
48 | * Error messages and icons.
49 | */
50 | error: palette.angry,
51 | tabbar: palette.ebony,
52 | callout: palette.purple,
53 | calloutShadow: palette.darkPurple,
54 | }
55 |
--------------------------------------------------------------------------------
/app/theme/fonts/index.ts:
--------------------------------------------------------------------------------
1 | // import * as Font from "expo-font"
2 |
3 | export const initFonts = async () => {
4 | // Refer to ./assets/fonts/custom-fonts.md for instructions.
5 | // ...
6 | // Welcome back! Just uncomment this and replace/append with your font file names!
7 | // ⬇
8 | // await Font.loadAsync({
9 | // Montserrat: require("./Montserrat-Regular.ttf"),
10 | // "Montserrat-Regular": require("./Montserrat-Regular.ttf"),
11 | // })
12 | }
13 |
--------------------------------------------------------------------------------
/app/theme/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./spacing"
2 | export * from "./typography"
3 | export * from "./timing"
4 | export * from "./palette"
5 | export * from "./color"
6 |
--------------------------------------------------------------------------------
/app/theme/palette.ts:
--------------------------------------------------------------------------------
1 | export const palette = {
2 | orange:'#FF8000',
3 | black: "#1d1d1d",
4 | white: "#ffffff",
5 | offWhite: "#C7C4DB",
6 | crimson: "#EC174F",
7 | ebony: "#10102A",
8 | portGore: "#161637",
9 | portGoreLight: "#1B1840",
10 | portGoreLighter: "#201B48",
11 | waterloo: "#878794",
12 | martinique: "#2C2C4C",
13 | mantiniqueLight: "#36325a",
14 | shamrock: "#56E39F",
15 | vintageRock: "rgba(86,227,159,0.20)",
16 | lightGrey: "#E6EAF4",
17 | lighterGrey: "#CDD4DA",
18 | haiti: "#0F0F30",
19 | angry: "#dd3333",
20 | purple: "#6600FF",
21 | darkPurple: "#0F0F30",
22 | }
23 |
--------------------------------------------------------------------------------
/app/theme/spacing.ts:
--------------------------------------------------------------------------------
1 | import { Dimensions } from "react-native"
2 |
3 | export const spacing = {
4 | tiny: 4,
5 | small: 10,
6 | medium: 14,
7 | large: 20,
8 | extraLarge: 43,
9 | huge: 80,
10 | ginormous: 100,
11 | }
12 |
13 | export const textSizes = {
14 | title: 24,
15 | }
16 |
17 | export const getScreenWidth = () => Dimensions.get("window").width
18 | export const getScreenHeight = () => Dimensions.get("window").height
19 |
20 | export const HIT_SLOP = {
21 | top: 20,
22 | left: 20,
23 | right: 20,
24 | bottom: 20,
25 | }
26 |
--------------------------------------------------------------------------------
/app/theme/timing.ts:
--------------------------------------------------------------------------------
1 | export const timing = {
2 | /**
3 | * The duration (ms) for quick animations.
4 | */
5 | quick: 300,
6 | }
7 |
--------------------------------------------------------------------------------
/app/theme/typography.ts:
--------------------------------------------------------------------------------
1 | import { Platform } from "react-native"
2 |
3 | /**
4 | * You can find a list of available fonts on both iOS and Android here:
5 | * https://github.com/react-native-training/react-native-fonts
6 | *
7 | * If you're interested in adding a custom font to your project,
8 | * check out the readme file in ./assets/fonts/ then come back here
9 | * and enter your new font name. Remember the Android font name
10 | * is probably different than iOS.
11 | * More on that here:
12 | * https://github.com/lendup/react-native-cross-platform-text
13 | *
14 | * The various styles of fonts are defined in the component.
15 | */
16 | export const typography = {
17 | /**
18 | * The primary font. Used in most places.
19 | */
20 | primary: Platform.select({ ios: "Helvetica", android: "normal" }),
21 |
22 | /**
23 | * An alternate font used for perhaps titles and stuff.
24 | */
25 | secondary: Platform.select({ ios: "Arial", android: "sans-serif" }),
26 |
27 | /**
28 | * Lets get fancy with a monospace font!
29 | */
30 | code: Platform.select({ ios: "Courier", android: "monospace" }),
31 | }
32 |
--------------------------------------------------------------------------------
/app/utils/delay.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * A "modern" sleep statement.
3 | *
4 | * @param ms The number of milliseconds to wait.
5 | */
6 | export const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))
7 |
--------------------------------------------------------------------------------
/app/utils/ignore-warnings.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Ignore some yellowbox warnings. Some of these are for deprecated functions
3 | * that we haven't gotten around to replacing yet.
4 | */
5 | import { LogBox } from "react-native"
6 |
7 | // prettier-ignore
8 | LogBox.ignoreLogs([
9 | "Require cycle:",
10 | ])
11 |
--------------------------------------------------------------------------------
/app/utils/info.ts:
--------------------------------------------------------------------------------
1 | export const TIMEZONE = "America/Los_Angeles"
2 |
--------------------------------------------------------------------------------
/app/utils/keychain.ts:
--------------------------------------------------------------------------------
1 | import * as ReactNativeKeychain from "react-native-keychain"
2 |
3 | /**
4 | * Saves some credentials securely.
5 | *
6 | * @param username The username
7 | * @param password The password
8 | * @param server The server these creds are for.
9 | */
10 | export async function save(username: string, password: string, server?: string) {
11 | if (server) {
12 | await ReactNativeKeychain.setInternetCredentials(server, username, password)
13 | return true
14 | } else {
15 | return ReactNativeKeychain.setGenericPassword(username, password)
16 | }
17 | }
18 |
19 | /**
20 | * Loads credentials that were already saved.
21 | *
22 | * @param server The server that these creds are for
23 | */
24 | export async function load(server?: string) {
25 | if (server) {
26 | const creds = await ReactNativeKeychain.getInternetCredentials(server)
27 | return {
28 | username: creds ? creds.username : null,
29 | password: creds ? creds.password : null,
30 | server,
31 | }
32 | } else {
33 | const creds = await ReactNativeKeychain.getGenericPassword()
34 | if (typeof creds === "object") {
35 | return {
36 | username: creds.username,
37 | password: creds.password,
38 | server: null,
39 | }
40 | } else {
41 | return {
42 | username: null,
43 | password: null,
44 | server: null,
45 | }
46 | }
47 | }
48 | }
49 |
50 | /**
51 | * Resets any existing credentials for the given server.
52 | *
53 | * @param server The server which has these creds
54 | */
55 | export async function reset(server?: string) {
56 | if (server) {
57 | await ReactNativeKeychain.resetInternetCredentials(server)
58 | return true
59 | } else {
60 | const result = await ReactNativeKeychain.resetGenericPassword()
61 | return result
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/app/utils/storage/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./storage"
2 |
--------------------------------------------------------------------------------
/app/utils/storage/storage.test.ts:
--------------------------------------------------------------------------------
1 | import AsyncStorage from "@react-native-async-storage/async-storage"
2 | import { load, loadString, save, saveString, clear, remove } from "./storage"
3 |
4 | // fixtures
5 | const VALUE_OBJECT = { x: 1 }
6 | const VALUE_STRING = JSON.stringify(VALUE_OBJECT)
7 |
8 | beforeEach(() => (AsyncStorage.getItem as jest.Mock).mockReturnValue(Promise.resolve(VALUE_STRING)))
9 | afterEach(() => jest.clearAllMocks())
10 |
11 | test("load", async () => {
12 | const value = await load("something")
13 | expect(value).toEqual(JSON.parse(VALUE_STRING))
14 | })
15 |
16 | test("loadString", async () => {
17 | const value = await loadString("something")
18 | expect(value).toEqual(VALUE_STRING)
19 | })
20 |
21 | test("save", async () => {
22 | await save("something", VALUE_OBJECT)
23 | expect(AsyncStorage.setItem).toHaveBeenCalledWith("something", VALUE_STRING)
24 | })
25 |
26 | test("saveString", async () => {
27 | await saveString("something", VALUE_STRING)
28 | expect(AsyncStorage.setItem).toHaveBeenCalledWith("something", VALUE_STRING)
29 | })
30 |
31 | test("remove", async () => {
32 | await remove("something")
33 | expect(AsyncStorage.removeItem).toHaveBeenCalledWith("something")
34 | })
35 |
36 | test("clear", async () => {
37 | await clear()
38 | expect(AsyncStorage.clear).toHaveBeenCalledWith()
39 | })
40 |
--------------------------------------------------------------------------------
/app/utils/storage/storage.ts:
--------------------------------------------------------------------------------
1 | import AsyncStorage from "@react-native-async-storage/async-storage"
2 |
3 | /**
4 | * Loads a string from storage.
5 | *
6 | * @param key The key to fetch.
7 | */
8 | export async function loadString(key: string): Promise {
9 | try {
10 | return await AsyncStorage.getItem(key)
11 | } catch {
12 | // not sure why this would fail... even reading the RN docs I'm unclear
13 | return null
14 | }
15 | }
16 |
17 | /**
18 | * Saves a string to storage.
19 | *
20 | * @param key The key to fetch.
21 | * @param value The value to store.
22 | */
23 | export async function saveString(key: string, value: string): Promise {
24 | try {
25 | await AsyncStorage.setItem(key, value)
26 | return true
27 | } catch {
28 | return false
29 | }
30 | }
31 |
32 | /**
33 | * Loads something from storage and runs it thru JSON.parse.
34 | *
35 | * @param key The key to fetch.
36 | */
37 | export async function load(key: string): Promise {
38 | try {
39 | const almostThere = await AsyncStorage.getItem(key)
40 | return JSON.parse(almostThere)
41 | } catch {
42 | return null
43 | }
44 | }
45 |
46 | /**
47 | * Saves an object to storage.
48 | *
49 | * @param key The key to fetch.
50 | * @param value The value to store.
51 | */
52 | export async function save(key: string, value: any): Promise {
53 | try {
54 | await AsyncStorage.setItem(key, JSON.stringify(value))
55 | return true
56 | } catch {
57 | return false
58 | }
59 | }
60 |
61 | /**
62 | * Removes something from storage.
63 | *
64 | * @param key The key to kill.
65 | */
66 | export async function remove(key: string): Promise {
67 | try {
68 | await AsyncStorage.removeItem(key)
69 | } catch {}
70 | }
71 |
72 | /**
73 | * Burn it all to the ground.
74 | */
75 | export async function clear(): Promise {
76 | try {
77 | await AsyncStorage.clear()
78 | } catch {}
79 | }
80 |
--------------------------------------------------------------------------------
/assets/images/adaptive-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/assets/images/adaptive-icon.png
--------------------------------------------------------------------------------
/assets/images/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/assets/images/favicon.png
--------------------------------------------------------------------------------
/assets/images/icon-default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/assets/images/icon-default.png
--------------------------------------------------------------------------------
/assets/images/icon-ios.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/assets/images/icon-ios.png
--------------------------------------------------------------------------------
/assets/images/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/assets/images/icon.png
--------------------------------------------------------------------------------
/assets/images/splash-tablet-landscape.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/assets/images/splash-tablet-landscape.png
--------------------------------------------------------------------------------
/assets/images/splash-tablet-portrait.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/assets/images/splash-tablet-portrait.png
--------------------------------------------------------------------------------
/assets/images/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinitered/ChainReactApp2022/712d48c73f55f33298c3d3e089df670f9488a375/assets/images/splash.png
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: ["babel-preset-expo"],
3 | env: {
4 | production: {},
5 | },
6 | plugins: [
7 | [
8 | "@babel/plugin-proposal-decorators",
9 | {
10 | legacy: true,
11 | },
12 | ],
13 | ["@babel/plugin-proposal-optional-catch-binding"],
14 | ],
15 | }
16 |
--------------------------------------------------------------------------------
/bin/downloadExpoApp.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash -e
2 |
3 | set -euo pipefail
4 |
5 | # based on https://github.com/yaron1m/expo-detox-typescript-example/blob/master/scripts/dl_expo_bins
6 | APP_PATH=./bin/Exponent.app
7 |
8 | if [ ! -d $APP_PATH ]; then
9 | echo "First time running Detox -- downloading Expo client app"
10 |
11 | # Sanity check
12 | if [ ! -f "package.json" ]; then
13 | echo "Oops - run this command from your project's root folder" >>/dev/stderr
14 | exit 1
15 | fi
16 |
17 | # Make the app dir (this'll also make sure we already have the bin directory)
18 | mkdir $APP_PATH
19 |
20 | # query expo.io to find most recent ipaUrl
21 | IPA_URL=`curl --silent --show-error https://expo.io/--/api/v2/versions | python -c 'import sys, json; print json.load(sys.stdin)["iosUrl"]'`
22 |
23 | # download tar.gz
24 | TMP_PATH=./exponent.tar.gz
25 | curl --silent --show-error --output $TMP_PATH $IPA_URL
26 |
27 | # unzip tar.gz into APP_PATH
28 | tar -C $APP_PATH -xzf $TMP_PATH
29 | rm ./exponent.tar.gz
30 | fi
31 |
--------------------------------------------------------------------------------
/bin/postInstall:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const childProcess = require("child_process")
4 | const os = require("os")
5 |
6 | /**
7 | * Do all things that need to be done after installing packages
8 | *
9 | * Yes, it slows down package installation a little, but it's nice to not
10 | * have to remember these extra steps.
11 | */
12 | ;[
13 | // Patch all the necessary modules.
14 | { command: "npx patch-package" },
15 |
16 | // Make sure we're set up correctly
17 | { command: "solidarity" },
18 |
19 | // Kill the metro bundler if it's running.
20 | { command: 'pkill -f "cli.js start" || set exit 0', onlyPlatforms: ["darwin", "linux"] },
21 | // Help wanted: Add the windows version here. { command: "????", onlyPlatforms: ["win32"] },
22 |
23 | // Make sure our native modules are androidX-happy
24 | { command: "jetify" },
25 |
26 | // on iOS, make sure our native modules are installed
27 | { command: "pod install", cwd: "ios", onlyPlatforms: ["darwin"] },
28 | ]
29 | .filter(({ onlyPlatforms }) => !onlyPlatforms || onlyPlatforms.includes(os.platform()))
30 | .forEach((commandAndOptions) => {
31 | const { command, onlyPlatform: _, ...options } = commandAndOptions
32 | try {
33 | childProcess.execSync(command, {
34 | stdio: "inherit",
35 | ...options,
36 | })
37 | } catch (error) {
38 | process.exit(error.status)
39 | }
40 | })
41 |
--------------------------------------------------------------------------------
/e2e/README.md:
--------------------------------------------------------------------------------
1 | # Detox End-To-End Testing
2 |
3 | ## Setup
4 |
5 | To get your Detox tests up and running, you'll need to install some global dependencies:
6 |
7 | 1. Install the latest version of [Homebrew](https://brew.sh/)
8 | 2. Make sure you have Node installed (at least 8.6.0). If you don't:
9 |
10 | If you use NVM:
11 |
12 | ```bash
13 | nvm install node
14 | ```
15 |
16 | Or if you'd prefer to install directly from Homebrew
17 |
18 | ```bash
19 | brew update && brew install node
20 | ```
21 |
22 | 3. Install `applesimutils, which will allow Detox to communicate with the iOS simulator:
23 |
24 | ```bash
25 | brew tap wix/brew && brew install applesimutils
26 | ```
27 |
28 | 4. Install the Detox CLI
29 |
30 | ```bash
31 | yarn global add detox-cli
32 | ```
33 |
34 | ## Adding tests
35 |
36 | We've gotten you started with `./e2e/firstTest.spec.js`, which tests that the two main example screens render properly.
37 |
38 | Note that in order to pick up elements by ID, we've added the `testID` prop to the component.
39 |
40 | ## Running tests
41 |
42 | 1. Start the packager
43 |
44 | ```
45 | yarn start
46 | ```
47 |
48 | _(Expo-only note: for testing [production code](https://docs.expo.io/workflow/development-mode/#production-mode), start the packager with `yarn start --no-dev --minify`)_
49 |
50 | 2. Run the app
51 |
52 | In a separate terminal window from the packager:
53 |
54 | ```
55 | yarn build:e2e
56 | ```
57 |
58 | _(Expo-only note: this is unnecessary for Expo apps)_
59 |
60 | 3. Run the tests
61 |
62 | ```
63 | yarn test:e2e
64 | ```
65 |
66 | For more information, make sure to check out the official [Detox Docs](https://github.com/wix/Detox/blob/master/docs/README.md)
67 |
--------------------------------------------------------------------------------
/e2e/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "setupFilesAfterEnv": ["./init.js"],
3 | "testEnvironment": "node"
4 | }
5 |
--------------------------------------------------------------------------------
/e2e/firstTest.spec.js:
--------------------------------------------------------------------------------
1 | // For more info on how to write Detox tests, see the official docs:
2 | // https://github.com/wix/Detox/blob/master/docs/README.md
3 |
4 | const { reloadApp } = require("./reload")
5 |
6 | describe("Example", () => {
7 | beforeEach(async () => {
8 | await reloadApp()
9 | })
10 |
11 | it("should have welcome screen", async () => {
12 | await expect(element(by.id("WelcomeScreen"))).toBeVisible()
13 | })
14 |
15 | it("should go to next screen after tap", async () => {
16 | await element(by.id("next-screen-button")).tap()
17 | await expect(element(by.id("DemoScreen"))).toBeVisible()
18 | })
19 | })
20 |
--------------------------------------------------------------------------------
/e2e/init.js:
--------------------------------------------------------------------------------
1 | const detox = require("detox")
2 | const config = require("../package.json").detox
3 | const adapter = require("detox/runners/jest/adapter")
4 |
5 | jest.setTimeout(120000)
6 | jasmine.getEnv().addReporter(adapter)
7 |
8 | beforeAll(async () => {
9 | await detox.init(config)
10 | })
11 |
12 | beforeEach(async () => {
13 | await adapter.beforeEach()
14 | })
15 |
16 | afterAll(async () => {
17 | await adapter.afterAll()
18 | await detox.cleanup()
19 | })
20 |
--------------------------------------------------------------------------------
/e2e/reload.js:
--------------------------------------------------------------------------------
1 | const { reloadApp } = require("detox-expo-helpers")
2 | module.exports = { reloadApp }
3 |
--------------------------------------------------------------------------------
/eas.json:
--------------------------------------------------------------------------------
1 | {
2 | "build": {
3 | "production": {},
4 | "development": {
5 | "developmentClient": true,
6 | "distribution": "internal"
7 | }
8 | },
9 | "submit": {
10 | "production": {}
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/ignite/templates/component/NAME.story.tsx.ejs:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { storiesOf } from "@storybook/react-native"
3 | import { StoryScreen, Story, UseCase } from "../../../storybook/views"
4 | import { color } from "../../theme"
5 | import { <%= props.pascalCaseName %> } from "./<%= props.kebabCaseName %>"
6 |
7 | storiesOf("<%= props.pascalCaseName %>", module)
8 | .addDecorator((fn) => {fn()})
9 | .add("Style Presets", () => (
10 |
11 |
12 | <<%= props.pascalCaseName %> style={{ backgroundColor: color.error }} />
13 |
14 |
15 | ))
16 |
--------------------------------------------------------------------------------
/ignite/templates/component/NAME.tsx.ejs:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { StyleProp, TextStyle, View, ViewStyle } from "react-native"
3 | import { observer } from "mobx-react-lite"
4 | import { color, typography } from "../../theme"
5 | import { Text } from "../"
6 | import { flatten } from "ramda"
7 |
8 | const CONTAINER: ViewStyle = {
9 | justifyContent: "center",
10 | }
11 |
12 | const TEXT: TextStyle = {
13 | fontFamily: typography.primary,
14 | fontSize: 14,
15 | color: color.primary,
16 | }
17 |
18 | export interface <%= props.pascalCaseName %>Props {
19 | /**
20 | * An optional style override useful for padding & margin.
21 | */
22 | style?: StyleProp
23 | }
24 |
25 | /**
26 | * Describe your component here
27 | */
28 | export const <%= props.pascalCaseName %> = observer(function <%= props.pascalCaseName %>(props: <%= props.pascalCaseName %>Props) {
29 | const { style } = props
30 | const styles = flatten([CONTAINER, style])
31 |
32 | return (
33 |
34 | Hello
35 |
36 | )
37 | })
38 |
--------------------------------------------------------------------------------
/ignite/templates/model/NAME.test.ts.ejs:
--------------------------------------------------------------------------------
1 | import { <%= props.pascalCaseName %>Model } from "./<%= props.kebabCaseName %>"
2 |
3 | test("can be created", () => {
4 | const instance = <%= props.pascalCaseName %>Model.create({})
5 |
6 | expect(instance).toBeTruthy()
7 | })
8 |
--------------------------------------------------------------------------------
/ignite/templates/model/NAME.ts.ejs:
--------------------------------------------------------------------------------
1 | import { Instance, SnapshotOut, types } from "mobx-state-tree"
2 |
3 | /**
4 | * Model description here for TypeScript hints.
5 | */
6 | export const <%= props.pascalCaseName %>Model = types
7 | .model("<%= props.pascalCaseName %>")
8 | .props({})
9 | .views((self) => ({})) // eslint-disable-line @typescript-eslint/no-unused-vars
10 | .actions((self) => ({})) // eslint-disable-line @typescript-eslint/no-unused-vars
11 |
12 | type <%= props.pascalCaseName %>Type = InstanceModel>
13 | export interface <%= props.pascalCaseName %> extends <%= props.pascalCaseName %>Type {}
14 | type <%= props.pascalCaseName %>SnapshotType = SnapshotOutModel>
15 | export interface <%= props.pascalCaseName %>Snapshot extends <%= props.pascalCaseName %>SnapshotType {}
16 | export const create<%= props.pascalCaseName %>DefaultModel = () => types.optional(<%= props.pascalCaseName %>Model, {})
17 |
--------------------------------------------------------------------------------
/ignite/templates/navigator/NAME-navigator.tsx.ejs:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { createStackNavigator } from "@react-navigation/stack"
3 | import {
4 | DemoScreen
5 | } from "../../screens"
6 |
7 | export type <%= props.pascalCaseName %>ParamList = {
8 | demo: undefined
9 | }
10 |
11 | const Stack = createStackNavigator<<%= props.pascalCaseName %>ParamList>()
12 | export const <%= props.pascalCaseName %> = () => {
13 | return (
14 |
15 |
16 |
17 | )
18 | }
19 |
--------------------------------------------------------------------------------
/ignite/templates/screen/NAME-screen.tsx.ejs:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { observer } from "mobx-react-lite"
3 | import { ViewStyle } from "react-native"
4 | import { Screen, Text } from "../../components"
5 | // import { useNavigation } from "@react-navigation/native"
6 | // import { useStores } from "../../models"
7 | import { color } from "../../theme"
8 |
9 | const ROOT: ViewStyle = {
10 | backgroundColor: color.palette.black,
11 | flex: 1,
12 | }
13 |
14 | export const <%= props.pascalCaseName %>Screen = observer(function <%= props.pascalCaseName %>Screen() {
15 | // Pull in one of our MST stores
16 | // const { someStore, anotherStore } = useStores()
17 |
18 | // Pull in navigation via hook
19 | // const navigation = useNavigation()
20 | return (
21 |
22 |
23 |
24 | )
25 | })
26 |
--------------------------------------------------------------------------------
/react-native.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | assets: ["./assets/fonts/"],
3 | }
4 |
--------------------------------------------------------------------------------
/storybook/index.ts:
--------------------------------------------------------------------------------
1 | // this is the native storybook entry point
2 | // import { StorybookUI } from "./config"
3 |
4 | export * from "./storybook"
5 |
--------------------------------------------------------------------------------
/storybook/storybook-registry.ts:
--------------------------------------------------------------------------------
1 | require("../app/components/text/text.story")
2 | require("../app/components/auto-image/auto-image.story")
3 | require("../app/components/button/button.story")
4 | require("../app/components/form-row/form-row.story")
5 | require("../app/components/switch/switch.story")
6 | require("../app/components/text-field/text-field.story")
7 | require("../app/components/checkbox/checkbox.story")
8 | require("../app/components/wallpaper/wallpaper.story")
9 | require("../app/components/gradient-background/gradient-background.story")
10 | require("../app/components/icon/icon.story")
11 | require("../app/components/header/header.story")
12 |
--------------------------------------------------------------------------------
/storybook/storybook.tsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect } from "react"
2 | import { getStorybookUI, configure } from "@storybook/react-native"
3 | import { initFonts } from "../app/theme/fonts"
4 |
5 | declare let module
6 |
7 | configure(() => {
8 | require("./storybook-registry")
9 | }, module)
10 |
11 | const StorybookUI = getStorybookUI({
12 | port: 9001,
13 | host: "localhost",
14 | onDeviceUI: true,
15 | asyncStorage: require("@react-native-async-storage/async-storage").default || null,
16 | })
17 |
18 | export function StorybookUIRoot() {
19 | useEffect(() => {
20 | ;(async () => {
21 | await initFonts() // expo only
22 | if (typeof __TEST__ === "undefined" || !__TEST__) {
23 | const Reactotron = require("../app/services/reactotron")
24 | const reactotron = new Reactotron.Reactotron()
25 | reactotron.setup()
26 | }
27 | })()
28 | }, [])
29 |
30 | return
31 | }
32 |
--------------------------------------------------------------------------------
/storybook/toggle-storybook.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from "react"
2 | import { DevSettings } from "react-native"
3 | import { loadString, saveString } from "../app/utils/storage"
4 |
5 | /**
6 | * Toggle Storybook mode, in __DEV__ mode only.
7 | *
8 | * In non-__DEV__ mode, or when Storybook isn't toggled on,
9 | * renders its children.
10 | *
11 | * The mode flag is persisted in async storage, which means it
12 | * persists across reloads/restarts - this is handy when developing
13 | * new components in Storybook.
14 | */
15 | export function ToggleStorybook(props) {
16 | const [showStorybook, setShowStorybook] = useState(false)
17 | const [StorybookUIRoot, setStorybookUIRoot] = useState(null)
18 |
19 | useEffect(() => {
20 | if (__DEV__ && DevSettings) {
21 | // Load the setting from storage if it's there
22 | loadString("devStorybook").then((storedSetting) => {
23 | // Set the initial value
24 | setShowStorybook(storedSetting === "on")
25 |
26 | // Add our toggle command to the menu
27 | DevSettings.addMenuItem("Toggle Storybook", () => {
28 | setShowStorybook((show) => {
29 | // On toggle, flip the current value
30 | show = !show
31 |
32 | // Write it back to storage
33 | saveString("devStorybook", show ? "on" : "off")
34 |
35 | // Return it to change the local state
36 | return show
37 | })
38 | })
39 |
40 | // Load the storybook UI once
41 | setStorybookUIRoot(() => require("./storybook").StorybookUIRoot)
42 | })
43 | }
44 | }, [])
45 |
46 | if (showStorybook) {
47 | return StorybookUIRoot ? : null
48 | } else {
49 | return props.children
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/storybook/toggle-storybook.web.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from "react"
2 | import * as QueryString from "query-string"
3 |
4 | interface StorybookQueryParams {
5 | storybook?: boolean
6 | }
7 |
8 | export const ToggleStorybook = (props) => {
9 | const [StorybookUIRoot, setStorybookUIRoot] = useState(null)
10 | const [queryParams, setQueryParams] = useState({})
11 |
12 | useEffect(() => {
13 | if (__DEV__) {
14 | // Load the storybook UI once
15 | setStorybookUIRoot(() => require("./storybook").StorybookUIRoot)
16 | }
17 | }, [])
18 |
19 | useEffect(() => {
20 | if (__DEV__) {
21 | setQueryParams(QueryString.parse(window.location.search))
22 | }
23 | }, [window.location.search])
24 |
25 | if (queryParams?.storybook) {
26 | return StorybookUIRoot ? : null
27 | } else {
28 | return props.children
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/storybook/views/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./story-screen"
2 | export * from "./story"
3 | export * from "./use-case"
4 |
--------------------------------------------------------------------------------
/storybook/views/story-screen.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { ViewStyle, KeyboardAvoidingView, Platform } from "react-native"
3 |
4 | const ROOT: ViewStyle = { backgroundColor: "#f0f0f0", flex: 1 }
5 |
6 | export interface StoryScreenProps {
7 | children?: React.ReactNode
8 | }
9 |
10 | const behavior = Platform.OS === "ios" ? "padding" : undefined
11 | export const StoryScreen = (props: StoryScreenProps) => (
12 |
13 | {props.children}
14 |
15 | )
16 |
--------------------------------------------------------------------------------
/storybook/views/story.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { ScrollView, View, ViewStyle } from "react-native"
3 |
4 | export interface StoryProps {
5 | children?: React.ReactNode
6 | }
7 |
8 | const ROOT: ViewStyle = { flex: 1 }
9 |
10 | export function Story(props: StoryProps) {
11 | return (
12 |
13 | {props.children}
14 |
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/test/mock-async-storage.ts:
--------------------------------------------------------------------------------
1 | import mockAsyncStorage from "@react-native-async-storage/async-storage/jest/async-storage-mock"
2 |
3 | jest.mock("@react-native-async-storage/async-storage", () => mockAsyncStorage)
4 |
--------------------------------------------------------------------------------
/test/mock-file.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | height: 100,
3 | width: 100,
4 | scale: 2.0,
5 | uri: "https://placekitten.com/200/200",
6 | }
7 |
--------------------------------------------------------------------------------
/test/mock-i18n.ts:
--------------------------------------------------------------------------------
1 | jest.mock("i18n-js", () => {
2 | return {
3 | t: (key) => `${key}.test`,
4 | }
5 | })
6 |
--------------------------------------------------------------------------------
/test/mock-react-native-image.ts:
--------------------------------------------------------------------------------
1 | import * as ReactNative from "react-native"
2 | import mockFile from "./mock-file"
3 |
4 | jest.doMock("react-native", () => {
5 | // Extend ReactNative
6 | return Object.setPrototypeOf(
7 | {
8 | Image: {
9 | ...ReactNative.Image,
10 | resolveAssetSource: jest.fn((source) => mockFile), // eslint-disable-line @typescript-eslint/no-unused-vars
11 | getSize: jest.fn(
12 | (
13 | uri: string, // eslint-disable-line @typescript-eslint/no-unused-vars
14 | success: (width: number, height: number) => void,
15 | failure?: (error: any) => void, // eslint-disable-line @typescript-eslint/no-unused-vars
16 | ) => success(100, 100),
17 | ),
18 | },
19 | },
20 | ReactNative,
21 | )
22 | })
23 |
--------------------------------------------------------------------------------
/test/mock-reactotron.ts:
--------------------------------------------------------------------------------
1 | declare const tron // eslint-disable-line @typescript-eslint/no-unused-vars
2 |
--------------------------------------------------------------------------------
/test/setup.ts:
--------------------------------------------------------------------------------
1 | // we always make sure 'react-native' gets included first
2 | import "react-native"
3 |
4 | // libraries to mock
5 | import "./mock-react-native-image"
6 | import "./mock-async-storage"
7 | import "./mock-i18n"
8 | import "./mock-reactotron"
9 |
10 | jest.useFakeTimers()
11 | declare global {
12 | let __TEST__
13 | }
14 |
--------------------------------------------------------------------------------
/test/storyshots.test.ts:
--------------------------------------------------------------------------------
1 | import initStoryshots from "@storybook/addon-storyshots"
2 |
3 | initStoryshots({
4 | configPath: "./storybook",
5 | framework: "react-native",
6 | })
7 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "allowJs": false,
4 | "allowSyntheticDefaultImports": true,
5 | "experimentalDecorators": true,
6 | "jsx": "react-native",
7 | "module": "es2015",
8 | "moduleResolution": "node",
9 | "noImplicitAny": false,
10 | "noImplicitReturns": true,
11 | "noImplicitThis": true,
12 | "noUnusedLocals": true,
13 | "sourceMap": true,
14 | "target": "esnext",
15 | "lib": [
16 | "esnext",
17 | "dom"
18 | ],
19 | "skipLibCheck": true,
20 | "resolveJsonModule": true
21 | },
22 | "exclude": [
23 | "node_modules"
24 | ],
25 | "include": [
26 | "App.js",
27 | "app",
28 | "test",
29 | "storybook"
30 | ],
31 | "extends": "expo/tsconfig.base"
32 | }
33 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const createExpoWebpackConfigAsync = require("@expo/webpack-config")
2 |
3 | // Expo CLI will await this method so you can optionally return a promise.
4 | module.exports = async function (env, argv) {
5 | const config = await createExpoWebpackConfigAsync(env, argv)
6 | // If you want to add a new alias to the config.
7 | // config.resolve.alias["moduleA"] = "moduleB"
8 |
9 | // Maybe you want to turn off compression in dev mode.
10 | if (config.mode === "development") {
11 | config.devServer.compress = false
12 | }
13 |
14 | // Or prevent minimizing the bundle when you build.
15 | // if (config.mode === "production") {
16 | // config.optimization.minimize = false
17 | // }
18 |
19 | // Finally return the new config for the CLI to use.
20 | return config
21 | }
22 |
--------------------------------------------------------------------------------