├── .buckconfig ├── .eslintrc.js ├── .flowconfig ├── .gitattributes ├── .gitignore ├── .gitmodules ├── .prettierrc.js ├── .watchmanconfig ├── App.js ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── StubbedApp.js ├── __tests__ └── App-test.js ├── android ├── app │ ├── BUCK │ ├── build.gradle │ ├── build_defs.bzl │ ├── proguard-rules.pro │ └── src │ │ ├── debug │ │ └── AndroidManifest.xml │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ └── com │ │ │ └── glider │ │ │ ├── MainActivity.java │ │ │ └── MainApplication.java │ │ └── res │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── strings.xml │ │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle ├── app.json ├── babel.config.js ├── code-editor.js ├── draggable-view.js ├── index.js ├── ios ├── Glider-tvOS │ └── Info.plist ├── Glider-tvOSTests │ └── Info.plist ├── Glider.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ ├── Glider-tvOS.xcscheme │ │ └── Glider.xcscheme ├── Glider.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── Glider │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Base.lproj │ │ └── LaunchScreen.xib │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Info.plist │ └── main.m ├── GliderTests │ ├── GliderTests.m │ └── Info.plist ├── Podfile └── Podfile.lock ├── logo.png ├── metro.config.js ├── old-app.js ├── package-lock.json ├── package.json ├── status.js ├── stubbed.py ├── template.config.js ├── template ├── .buckconfig ├── .eslintrc.js ├── .gitattributes ├── .gitignore ├── .prettierrc.js ├── .watchmanconfig ├── App.tsx ├── __tests__ │ └── App-test.tsx ├── android │ ├── app │ │ ├── BUCK │ │ ├── build.gradle │ │ ├── build_defs.bzl │ │ ├── proguard-rules.pro │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ └── com │ │ │ │ └── glider │ │ │ │ ├── MainActivity.java │ │ │ │ └── MainApplication.java │ │ │ └── res │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ └── values │ │ │ ├── strings.xml │ │ │ └── styles.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle ├── app.json ├── babel.config.js ├── index.js ├── ios │ ├── Glider-tvOS │ │ └── Info.plist │ ├── Glider-tvOSTests │ │ └── Info.plist │ ├── Glider.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ ├── Glider-tvOS.xcscheme │ │ │ └── Glider.xcscheme │ ├── Glider │ │ ├── AppDelegate.h │ │ ├── AppDelegate.m │ │ ├── Base.lproj │ │ │ └── LaunchScreen.xib │ │ ├── Images.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ ├── Info.plist │ │ └── main.m │ ├── GliderTests │ │ ├── GliderTests.m │ │ └── Info.plist │ └── Podfile └── metro.config.js └── yarn.lock /.buckconfig: -------------------------------------------------------------------------------- 1 | 2 | [android] 3 | target = Google Inc.:Google APIs:23 4 | 5 | [maven_repositories] 6 | central = https://repo1.maven.org/maven2 7 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: '@react-native-community', 4 | }; 5 | -------------------------------------------------------------------------------- /.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | ; We fork some components by platform 3 | .*/*[.]android.js 4 | 5 | ; Ignore "BUCK" generated dirs 6 | /\.buckd/ 7 | 8 | ; Ignore unexpected extra "@providesModule" 9 | .*/node_modules/.*/node_modules/fbjs/.* 10 | 11 | ; Ignore duplicate module providers 12 | ; For RN Apps installed via npm, "Libraries" folder is inside 13 | ; "node_modules/react-native" but in the source repo it is in the root 14 | node_modules/react-native/Libraries/react-native/React.js 15 | 16 | ; Ignore polyfills 17 | node_modules/react-native/Libraries/polyfills/.* 18 | 19 | ; These should not be required directly 20 | ; require from fbjs/lib instead: require('fbjs/lib/warning') 21 | node_modules/warning/.* 22 | 23 | ; Flow doesn't support platforms 24 | .*/Libraries/Utilities/HMRLoadingView.js 25 | 26 | [untyped] 27 | .*/node_modules/@react-native-community/cli/.*/.* 28 | 29 | [include] 30 | 31 | [libs] 32 | node_modules/react-native/Libraries/react-native/react-native-interface.js 33 | node_modules/react-native/flow/ 34 | 35 | [options] 36 | emoji=true 37 | 38 | esproposal.optional_chaining=enable 39 | esproposal.nullish_coalescing=enable 40 | 41 | module.file_ext=.js 42 | module.file_ext=.json 43 | module.file_ext=.ios.js 44 | 45 | module.system=haste 46 | module.system.haste.use_name_reducers=true 47 | # get basename 48 | module.system.haste.name_reducers='^.*/\([a-zA-Z0-9$_.-]+\.js\(\.flow\)?\)$' -> '\1' 49 | # strip .js or .js.flow suffix 50 | module.system.haste.name_reducers='^\(.*\)\.js\(\.flow\)?$' -> '\1' 51 | # strip .ios suffix 52 | module.system.haste.name_reducers='^\(.*\)\.ios$' -> '\1' 53 | module.system.haste.name_reducers='^\(.*\)\.android$' -> '\1' 54 | module.system.haste.name_reducers='^\(.*\)\.native$' -> '\1' 55 | module.system.haste.paths.blacklist=.*/__tests__/.* 56 | module.system.haste.paths.blacklist=.*/__mocks__/.* 57 | module.system.haste.paths.whitelist=/node_modules/react-native/Libraries/.* 58 | module.system.haste.paths.whitelist=/node_modules/react-native/RNTester/.* 59 | module.system.haste.paths.whitelist=/node_modules/react-native/IntegrationTests/.* 60 | module.system.haste.paths.blacklist=/node_modules/react-native/Libraries/react-native/react-native-implementation.js 61 | module.system.haste.paths.blacklist=/node_modules/react-native/Libraries/Animated/src/polyfills/.* 62 | 63 | munge_underscores=true 64 | 65 | module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub' 66 | 67 | suppress_type=$FlowIssue 68 | suppress_type=$FlowFixMe 69 | suppress_type=$FlowFixMeProps 70 | suppress_type=$FlowFixMeState 71 | 72 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\) 73 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)?:? #[0-9]+ 74 | suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError 75 | 76 | [lints] 77 | sketchy-null-number=warn 78 | sketchy-null-mixed=warn 79 | sketchy-number=warn 80 | untyped-type-import=warn 81 | nonstrict-import=warn 82 | deprecated-type=warn 83 | unsafe-getters-setters=warn 84 | inexact-spread=warn 85 | unnecessary-invariant=warn 86 | signature-verification-failure=warn 87 | deprecated-utility=error 88 | 89 | [strict] 90 | deprecated-type 91 | nonstrict-import 92 | sketchy-null 93 | unclear-type 94 | unsafe-getters-setters 95 | untyped-import 96 | untyped-type-import 97 | 98 | [version] 99 | ^0.98.0 100 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | -------------------------------------------------------------------------------- /.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 | project.xcworkspace 24 | 25 | # Android/IntelliJ 26 | # 27 | build/ 28 | .idea 29 | .gradle 30 | local.properties 31 | *.iml 32 | android/captures/ 33 | 34 | # node.js 35 | # 36 | node_modules/ 37 | npm-debug.log 38 | yarn-error.log 39 | 40 | # BUCK 41 | buck-out/ 42 | \.buckd/ 43 | *.keystore 44 | 45 | # fastlane 46 | # 47 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 48 | # screenshots whenever they are needed. 49 | # For more information about the recommended setup visit: 50 | # https://docs.fastlane.tools/best-practices/source-control/ 51 | 52 | */fastlane/report.xml 53 | */fastlane/Preview.html 54 | */fastlane/screenshots 55 | 56 | # Bundle artifact 57 | *.jsbundle 58 | 59 | # CocoaPods 60 | /ios/Pods/ 61 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "pyright"] 2 | path = pyright 3 | url = git@github.com:adafruit/pyright.git 4 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | bracketSpacing: false, 3 | jsxBracketSameLine: true, 4 | singleQuote: true, 5 | trailingComma: 'all', 6 | }; 7 | -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /App.js: -------------------------------------------------------------------------------- 1 | 2 | import React, { useReducer, useState, useEffect } from 'react'; 3 | import 'react-native-gesture-handler'; 4 | import {Alert, TextInput, Text} from 'react-native'; 5 | import { NavigationContainer, DefaultTheme, DarkTheme } from '@react-navigation/native'; 6 | import { AppearanceProvider, useColorScheme} from 'react-native-appearance'; 7 | import DraggableView from './draggable-view'; 8 | import CodeEditor from './code-editor'; 9 | import Status, { StatusSummary} from './status'; 10 | import { useAppState } from 'react-native-hooks' 11 | import { stringToBytes, bytesToString } from 'convert-string'; 12 | import * as encoding from 'text-encoding'; 13 | import RNColorPalette from '@iomechs/rn-color-palette'; 14 | import Clipboard from "@react-native-community/clipboard"; 15 | import { 16 | NativeEventEmitter, 17 | NativeModules, 18 | PermissionsAndroid, 19 | Platform, 20 | View, 21 | TouchableOpacity, 22 | SafeAreaView 23 | } from 'react-native'; 24 | 25 | import BleManager from 'react-native-ble-manager'; 26 | import { ScrollView } from 'react-native-gesture-handler'; 27 | const BleManagerModule = NativeModules.BleManager; 28 | const bleManagerEmitter = new NativeEventEmitter(BleManagerModule); 29 | 30 | 31 | function peripheralReducer(state, action) { 32 | if (action.action == "add") { 33 | let peripheral = action.peripheral; 34 | //console.log(peripheral); 35 | if (state.has(peripheral.id)) { 36 | return state; // No state change 37 | } 38 | if (!peripheral.advertising.serviceUUIDs || peripheral.advertising.serviceUUIDs.length == 0 || peripheral.advertising.serviceUUIDs[0].toLowerCase() != 'adaf0100-4369-7263-7569-74507974686e') { 39 | return state; 40 | } 41 | //console.log(peripheral); 42 | var newMap = new Map(state); 43 | newMap.set(peripheral.id, peripheral); 44 | return newMap; 45 | } else if (action.action == "scan") { 46 | BleManager.scan([], 3).then((results) => { 47 | //console.log('Scanning...'); 48 | }); 49 | } else if (action.action == "clear") { 50 | state.clear(); 51 | } 52 | return state; 53 | } 54 | 55 | const service = 'adaf0100-4369-7263-7569-74507974686e'; 56 | const contentsCharacteristic = 'adaf0201-4369-7263-7569-74507974686e'; 57 | const filenameCharacteristic = 'adaf0200-4369-7263-7569-74507974686e'; 58 | const versionCharacteristic = 'adaf0203-4369-7263-7569-74507974686e'; 59 | const lengthCharacteristic = 'adaf0202-4369-7263-7569-74507974686e'; 60 | 61 | function codeReducer(state, action) { 62 | let newState = {code: state.code, peripheral_id: state.peripheral_id, queue: state.queue, version: state.version + 1}; 63 | if (action.type == "clear") { 64 | newState.code = ""; 65 | } else if (action.type == "connect") { 66 | newState.peripheral_id = action.peripheral_id; 67 | if (state.queue && state.queue.length > 0) { 68 | //console.log("missed patches", state.queue); 69 | } 70 | } else if (action.type == "disconnect") { 71 | newState.peripheral_id = null; 72 | newState.queue = new Array(); 73 | } else if (action.type == "read") { 74 | newState.code += action.data; 75 | } else if (action.type == "patch") { 76 | //console.log("TODO send data back to CP"); 77 | //console.log(state, action); 78 | let encoder = new encoding.TextEncoder(); 79 | let encodedInsert = encoder.encode(action.newValue); 80 | let totalLength = 2 + 2 + 4 + 4 + 4 + encodedInsert.length 81 | let patch = new ArrayBuffer(totalLength); 82 | let view = new DataView(patch); 83 | view.setUint16(0, totalLength, true); 84 | view.setUint16(2, 2, true); 85 | view.setUint32(4, action.offset, true); 86 | view.setUint32(8, action.oldValue.length, true); 87 | view.setUint32(12, encodedInsert.length, true); 88 | let byteView = new Uint8Array(patch, 16, encodedInsert.length); 89 | byteView.set(encodedInsert); 90 | 91 | // React native bridging can't handle Uint8Array so copy into a normal array. 92 | let finalPatch = Array.from(new Uint8Array(patch)); 93 | if (state.peripheral_id) { 94 | console.log("writing patch", finalPatch, patch); 95 | BleManager.write( 96 | state.peripheral_id, 97 | service, 98 | contentsCharacteristic, 99 | finalPatch 100 | ).then(() => { 101 | console.log('Wrote patch to device'); 102 | }).catch((error) => { 103 | console.log("ERROR patching: ", error); 104 | }); 105 | } else { 106 | console.log("no peripheral", newState.queue); 107 | newState.queue.push(patch); 108 | } 109 | 110 | //console.log("merging together", action, state.code); 111 | newState.code = state.code.substring(0, action.offset) + action.newValue + state.code.substring(action.offset + action.oldValue.length, state.code.length); 112 | } 113 | 114 | //console.log("new code state", newState); 115 | return newState; 116 | } 117 | 118 | export default function App() { 119 | //check if color scheme is set to dark 120 | const scheme = useColorScheme() 121 | const [dark, setDark] = useState(false); 122 | if (scheme == 'dark') { 123 | setDark(true); 124 | } 125 | 126 | //initialize variables and functions for color palette and clipboard feature 127 | const [pickedColor, colorPicked] = useState('#ff0000'); 128 | const [colors, addColor] = useState(['#ff0000']); 129 | 130 | const copyToClipboard = (pickedColor) => { 131 | let originalColor = pickedColor; 132 | let prefix = '0x' 133 | let newColor = originalColor.substring(1) 134 | let newHexColor = prefix.concat(newColor) 135 | console.log(newHexColor) 136 | Clipboard.setString(newHexColor) 137 | } 138 | 139 | //initalize constants and states for app 140 | const currentAppState = useAppState(); 141 | const [bleState, setBleState] = useState("stopped"); 142 | const [peripherals, changePeripherals] = useReducer(peripheralReducer, new Map()); 143 | const [peripheral, setPeripheral] = useState(null); 144 | const [fileState, setFileState] = useState("unloaded"); 145 | const [fileLength, setFileLength] = useState(-1); 146 | const [search, setSearch] = useState(""); 147 | 148 | const [code, changeCode] = useReducer(codeReducer, {code:"", version:0, peripheral_id: null}); 149 | 150 | 151 | useEffect(() => { 152 | if (currentAppState === 'active') { 153 | //console.log('App has come to the foreground!', bleState); 154 | BleManager.start({showAlert: true}); 155 | BleManager.checkState(); 156 | } else { 157 | if (peripheral) { 158 | changeCode({"type": "disconnect", "peripheral_id": peripheral.id}); 159 | BleManager.disconnect(peripheral.id); 160 | } 161 | 162 | setBleState("disconnected"); 163 | } 164 | }, [currentAppState]); 165 | 166 | const handleUpdateValueForCharacteristic = (data) => { 167 | //console.log(data); 168 | //console.log('Received data from ' + data.peripheral + ' characteristic ' + data.characteristic, bytesToString(data.value)); 169 | changeCode({"type": "read", "data": bytesToString(data.value)}); 170 | } 171 | 172 | const handleUpdateState = (data) => { 173 | //console.log("update state", data); 174 | if (data.state == "on") { 175 | //console.log("started"); 176 | setBleState("started"); 177 | } 178 | } 179 | 180 | const handleStopScan = () => { 181 | //console.log('Scan is stopped'); 182 | setBleState('selectPeripheral'); 183 | } 184 | 185 | const handleDiscoverPeripheral = (peripheral) => { 186 | //console.log('Got ble peripheral', peripheral); 187 | peripheral.connected = false; 188 | changePeripherals({"action": "add", "peripheral": peripheral}); 189 | } 190 | 191 | const handleDisconnectedPeripheral = (data) => { 192 | // let peripherals = this.state.peripherals; 193 | // let peripheral = peripherals.get(data.peripheral); 194 | // if (peripheral) { 195 | // peripheral.connected = false; 196 | // peripherals.set(peripheral.id, peripheral); 197 | // this.setState({peripherals}); 198 | // } 199 | setBleState("disconnected"); 200 | 201 | Alert.alert( 202 | "Device Disconnected", 203 | "You have lost connection with your device", 204 | [ 205 | { 206 | text: "Dismiss", 207 | } 208 | ], 209 | { cancelable: false } 210 | ); 211 | //console.log('Disconnected from ' + data.peripheral); 212 | } 213 | 214 | function handleConnectPeripheral() { 215 | //console.log("handle connect to", peripheral); 216 | BleManager.connect(peripheral.id).then(() => { 217 | setBleState("connected"); 218 | changeCode({"type": "connect", "peripheral_id": peripheral.id}); 219 | setTimeout(() => { 220 | 221 | BleManager.retrieveServices(peripheral.id).then((peripheralInfo) => { 222 | //console.log(peripheralInfo); 223 | 224 | setTimeout(() => { 225 | BleManager.startNotification(peripheral.id, service, contentsCharacteristic).then(() => { 226 | //console.log('Started notification on ' + peripheral.id); 227 | setTimeout(() => { 228 | BleManager.write(peripheral.id, service, filenameCharacteristic, stringToBytes("/code.py")).then(() => { 229 | //console.log('Wrote filename'); 230 | setFileState("nameSet"); 231 | }); 232 | 233 | }, 500); 234 | }).catch((error) => { 235 | //console.log('Notification error', error); 236 | }); 237 | }, 200); 238 | }); 239 | 240 | }, 900); 241 | }).catch((error) => { 242 | setBleState("disconnected"); 243 | console.log('Connection error', error); 244 | }); 245 | } 246 | 247 | useEffect(() => { 248 | if (fileState == "nameSet") { 249 | // Load the file length and then load it all. 250 | setTimeout(() => { 251 | BleManager.read(peripheral.id, service, lengthCharacteristic).then((readData) => { 252 | let length = readData[0] + (readData[1] << 8) + (readData[2] << 16) + (readData[3] << 24); 253 | //console.log('fileLength', readData, length); 254 | changeCode({"type": "clear"}); 255 | setFileLength(length); 256 | setFileState("loading"); 257 | }); 258 | 259 | }, 500); 260 | } else if (fileState == "loading") { 261 | let command = new Array(4); 262 | command.fill(0); 263 | command[0] = 4; 264 | command[2] = 1; 265 | setTimeout(() => { 266 | BleManager.write(peripheral.id, service, contentsCharacteristic, command) 267 | .catch((error) => { 268 | console.log('Command error', error); 269 | }); 270 | }, 200); 271 | } 272 | }, [fileState]); 273 | 274 | useEffect(() => { 275 | //console.log("loaded", code.code.length, fileLength); 276 | if (fileState == "loading" && code.code.length == fileLength) { 277 | setFileState("loaded"); 278 | } 279 | }, [code, fileState, fileLength]); 280 | 281 | useEffect(() => { 282 | if (peripheral != null && bleState != "connected") { 283 | handleConnectPeripheral(); 284 | } 285 | }, [peripheral, bleState]); 286 | 287 | useEffect(() => { 288 | //console.log("new blestate", bleState); 289 | if (bleState == "permOk") { 290 | } else if (bleState == "started") { 291 | changePeripherals({"action": "clear"}); 292 | BleManager.getConnectedPeripherals([]).then((peripheralsArray) => { 293 | for (p of peripheralsArray) { 294 | //console.log(p); 295 | p.connected = true; 296 | BleManager.connect(p.id).then(() => { 297 | BleManager.retrieveServices(p.id).then((peripheralInfo) => { 298 | //console.log(peripheralInfo); 299 | p.advertising.serviceUUIDs = [peripheralInfo.services[2].uuid]; 300 | changePeripherals({"action": "add", "peripheral": p}); 301 | }); 302 | }); 303 | } 304 | //console.log('Connected peripherals: ' + peripheralsArray.length); 305 | }); 306 | changePeripherals({"action": "scan"}); 307 | } else if (bleState == "disconnected") { 308 | // set a timeout and try to reconnect 309 | } else if (bleState == "selectPeripheral") { 310 | //console.log(peripherals, peripherals.values()); 311 | if (peripherals.size == 1) { 312 | let peripheral = [...peripherals][0][1]; 313 | //console.log("selecting", peripheral); 314 | setPeripheral(peripheral); 315 | } 316 | } 317 | }, [bleState]); 318 | 319 | useEffect(() => { 320 | const handlerDiscover = bleManagerEmitter.addListener('BleManagerDiscoverPeripheral', handleDiscoverPeripheral ); 321 | const handlerStop = bleManagerEmitter.addListener('BleManagerStopScan', handleStopScan ); 322 | const handlerDisconnect = bleManagerEmitter.addListener('BleManagerDisconnectPeripheral', handleDisconnectedPeripheral ); 323 | const handlerUpdate = bleManagerEmitter.addListener('BleManagerDidUpdateValueForCharacteristic', handleUpdateValueForCharacteristic ); 324 | const handlerUpdateState = bleManagerEmitter.addListener('BleManagerDidUpdateState', handleUpdateState); 325 | 326 | if (Platform.OS === 'android' && Platform.Version >= 23) { 327 | setBleState("permCheck"); 328 | PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION).then((result) => { 329 | if (result) { 330 | setBleState("permOk"); 331 | } else { 332 | PermissionsAndroid.requestPermission(PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION).then((result) => { 333 | if (result) { 334 | setBleState("permOk"); 335 | } else { 336 | setBleState("permNak"); 337 | } 338 | }); 339 | } 340 | }); 341 | } else { 342 | setBleState("permOk"); 343 | } 344 | 345 | return () => { 346 | handlerDiscover.remove(); 347 | handlerStop.remove(); 348 | handlerDisconnect.remove(); 349 | handlerUpdate.remove(); 350 | handlerUpdateState.remove(); 351 | }; 352 | }, []); 353 | 354 | return ( 355 | 356 | 357 | ( 362 | 363 | 364 | 365 | 366 | setSearch(search)} 379 | underlineColorAndroid="black" 380 | placeholder="Search through the code ..." 381 | placeholderTextColor={scheme === 'dark' ? 'white' : 'rgb(18,18,18)'} 382 | keyboardType="default" 383 | clearButtonMode="while-editing" 384 | /> 385 | 386 | 387 | 392 | addColor([...colors, colour])} 397 | style={{ 398 | backgroundColor: pickedColor, 399 | paddingLeft: 10, 400 | paddingRight: 5, 401 | paddingTop: 2, 402 | paddingBottom: 2, 403 | borderWidth: 1, 404 | borderRadius: 5, 405 | width: 140, 406 | height: 30, 407 | }}> 408 | 409 | Color Picker 410 | 411 | 412 | 423 | Copy to Clipboard 424 | 425 | 426 | 427 | 428 | 436 | 437 | 438 | )} 439 | renderDrawerView={() => ()} 440 | renderInitDrawerView={() => ()} 441 | 442 | /> 443 | 444 | 445 | ); 446 | 447 | } 448 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Adafruit Community Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and leaders pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level or type of 9 | experience, education, socio-economic status, nationality, personal appearance, 10 | race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | We are committed to providing a friendly, safe and welcoming environment for 15 | all. 16 | 17 | Examples of behavior that contributes to creating a positive environment 18 | include: 19 | 20 | * Be kind and courteous to others 21 | * Using welcoming and inclusive language 22 | * Being respectful of differing viewpoints and experiences 23 | * Collaborating with other community members 24 | * Gracefully accepting constructive criticism 25 | * Focusing on what is best for the community 26 | * Showing empathy towards other community members 27 | 28 | Examples of unacceptable behavior by participants include: 29 | 30 | * The use of sexualized language or imagery and sexual attention or advances 31 | * The use of inappropriate images, including in a community member's avatar 32 | * The use of inappropriate language, including in a community member's nickname 33 | * Any spamming, flaming, baiting or other attention-stealing behavior 34 | * Excessive or unwelcome helping; answering outside the scope of the question 35 | asked 36 | * Trolling, insulting/derogatory comments, and personal or political attacks 37 | * Public or private harassment 38 | * Publishing others' private information, such as a physical or electronic 39 | address, without explicit permission 40 | * Other conduct which could reasonably be considered inappropriate 41 | 42 | The goal of the standards and moderation guidelines outlined here is to build 43 | and maintain a respectful community. We ask that you don’t just aim to be 44 | "technically unimpeachable", but rather try to be your best self. 45 | 46 | We value many things beyond technical expertise, including collaboration and 47 | supporting others within our community. Providing a positive experience for 48 | other community members can have a much more significant impact than simply 49 | providing the correct answer. 50 | 51 | ## Our Responsibilities 52 | 53 | Project leaders are responsible for clarifying the standards of acceptable 54 | behavior and are expected to take appropriate and fair corrective action in 55 | response to any instances of unacceptable behavior. 56 | 57 | Project leaders have the right and responsibility to remove, edit, or 58 | reject messages, comments, commits, code, issues, and other contributions 59 | that are not aligned to this Code of Conduct, or to ban temporarily or 60 | permanently any community member for other behaviors that they deem 61 | inappropriate, threatening, offensive, or harmful. 62 | 63 | ## Moderation 64 | 65 | Instances of behaviors that violate the Adafruit Community Code of Conduct 66 | may be reported by any member of the community. Community members are 67 | encouraged to report these situations, including situations they witness 68 | involving other community members. 69 | 70 | You may report in the following ways: 71 | 72 | In any situation, you may send an email to . 73 | 74 | On the Adafruit Discord, you may send an open message from any channel 75 | to all Community Helpers by tagging @community moderators. You may also send an 76 | open message from any channel, or a direct message to @kattni#1507, 77 | @tannewt#4653, @Dan Halbert#1614, @cater#2442, @sommersoft#0222, or 78 | @Andon#8175. 79 | 80 | Email and direct message reports will be kept confidential. 81 | 82 | In situations on Discord where the issue is particularly egregious, possibly 83 | illegal, requires immediate action, or violates the Discord terms of service, 84 | you should also report the message directly to Discord. 85 | 86 | These are the steps for upholding our community’s standards of conduct. 87 | 88 | 1. Any member of the community may report any situation that violates the 89 | Adafruit Community Code of Conduct. All reports will be reviewed and 90 | investigated. 91 | 2. If the behavior is an egregious violation, the community member who 92 | committed the violation may be banned immediately, without warning. 93 | 3. Otherwise, moderators will first respond to such behavior with a warning. 94 | 4. Moderators follow a soft "three strikes" policy - the community member may 95 | be given another chance, if they are receptive to the warning and change their 96 | behavior. 97 | 5. If the community member is unreceptive or unreasonable when warned by a 98 | moderator, or the warning goes unheeded, they may be banned for a first or 99 | second offense. Repeated offenses will result in the community member being 100 | banned. 101 | 102 | ## Scope 103 | 104 | This Code of Conduct and the enforcement policies listed above apply to all 105 | Adafruit Community venues. This includes but is not limited to any community 106 | spaces (both public and private), the entire Adafruit Discord server, and 107 | Adafruit GitHub repositories. Examples of Adafruit Community spaces include 108 | but are not limited to meet-ups, audio chats on the Adafruit Discord, or 109 | interaction at a conference. 110 | 111 | This Code of Conduct applies both within project spaces and in public spaces 112 | when an individual is representing the project or its community. As a community 113 | member, you are representing our community, and are expected to behave 114 | accordingly. 115 | 116 | ## Attribution 117 | 118 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 119 | version 1.4, available at 120 | , 121 | and the [Rust Code of Conduct](https://www.rust-lang.org/en-US/conduct.html). 122 | 123 | For other projects adopting the Adafruit Community Code of 124 | Conduct, please contact the maintainers of those projects for enforcement. 125 | If you wish to use this code of conduct for your own project, consider 126 | explicitly mentioning your moderation policy or making a copy with your 127 | own moderation policy so as to avoid confusion. 128 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2019 Scott Shawcroft for Adafruit Industries 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Glider word logo](logo.png) 2 | 3 | Glider is a portable mobile app aimed at making wireless editing of Python code really easy and fun. 4 | 5 | ## Installation 6 | ``` 7 | git clone --recursive https://github.com/adafruit/glider.git 8 | ``` 9 | If pyright fails to install, run: 10 | ``` 11 | cd glider 12 | rm -rf pyright 13 | git clone https://github.com/adafruit/pyright 14 | ``` 15 | 16 | In the glider folder, run: 17 | ``` 18 | npm install 19 | ``` 20 | 21 | **NOTE:** Android requires manual installation/ linking of the libraries: 22 | - [react-native-fs](https://www.npmjs.com/package/react-native-fs#usage-android) 23 | - [react-native-local-resource](https://www.npmjs.com/package/react-native-local-resource) 24 | 25 | 26 | ### iOS 27 | From the /ios folder, run: 28 | ``` 29 | pod install 30 | ``` 31 | Open XCode and run on your device, it should ask for bluetooth permissions once loaded. Additionaly, the bundle identifiers may need to be changed for the code signing to work. 32 | 33 | ### Android 34 | 1) Build the gradle project by opening `glider/android` folder in Android Studio. Gradle should automatically start building and notify you when project is built via logs or Build tab. 35 | 2) If the `debug.keystore` file does not exist already in `glider/android/app`, then copy it from `glider/node_modules/react-native/template/android/app` or search for where this file exists in your glider folder and paste it to `glider/android/app`. 36 | 3) Connect your android device to your computer. **NOTE:** app must be run on physical device (not an Android Simulator) due to bluetooth limitations. 37 | 4) In VS Code, run: 38 | ``` 39 | npx react-native run-android 40 | ``` 41 | 42 | ### Adafruit board 43 | Ensure your board is running a BLE-allowed version of Circuit Python to allow your board to connect to glider. 44 | 45 | To revert back to version of Circuit Python with BLE enabled: 46 | ``` 47 | git clone https://github.com/adafruit/circuitpython.git 48 | cd circuitpython 49 | git checkout aca53aa1a2c21ff46b609cfc270134ee6ee024f2 50 | ``` 51 | 52 | Then rebuild Circuit Python onto your board following [these directions](https://learn.adafruit.com/building-circuitpython/build-circuitpython#build-circuitpython-2986723-5), replacing the last step with BLE flag: 53 | ``` 54 | cd ports/{insert_board_type_folder} 55 | make BOARD={insert_board_name} CIRCUITPY_BLE_FILE_SERVICE = 1 56 | ``` 57 | 58 | Then run your build following [these directions](https://learn.adafruit.com/building-circuitpython/build-circuitpython#run-your-build-2987858-9) and ensure `code.py` is actively running code to allow BLE detection. (Eg, [this](https://learn.adafruit.com/welcome-to-circuitpython/creating-and-editing-code#exploring-your-first-circuitpython-program-2977748-20) led sample code). 59 | 60 | *Optional:* To check whether BLE-allowed version of Circuit Python was installed correctly or not, download the [Adafruit Bluefruit LE Connect app](https://learn.adafruit.com/bluefruit-le-connect/ios-setup) and check that your board is detected. 61 | 62 | Upon refresh of glider app, your board should be automatically detected and connected. **NOTE:** may need to refresh glider more than once or may need to click reset button on board 63 | 64 | 65 | 66 | ## Usage 67 | Glider can run using code from either your BLE enabled CircuitPython device, or from a local file. 68 | 69 | To allow it to run on your CircuitPython device, you must first build CircuitPython using this commit (run git checkout followed by this hash): ```aca53aa1a2c21ff46b609cfc270134ee6ee024f2``` 70 | Use the instructions from [here](https://learn.adafruit.com/building-circuitpython) to build the code and upload it to your device. 71 | 72 | To test code from your local machine, put your code in stubbed.py and change the false value to true from this line in index.js: 73 | ``` 74 | const readFromFile = false; 75 | ``` 76 | 77 | ## :bookmark: License 78 | 79 | This project is [MIT](LICENSE) licensed. 80 | -------------------------------------------------------------------------------- /StubbedApp.js: -------------------------------------------------------------------------------- 1 | import React, { useReducer, useState, useEffect } from 'react'; 2 | import 'react-native-gesture-handler'; 3 | import {Alert, TextInput, Text} from 'react-native'; 4 | import { NavigationContainer, DefaultTheme, DarkTheme } from '@react-navigation/native'; 5 | import { AppearanceProvider, useColorScheme} from 'react-native-appearance'; 6 | import DraggableView from './draggable-view'; 7 | import CodeEditor from './code-editor'; 8 | import Status, { StatusSummary} from './status'; 9 | import { useAppState } from 'react-native-hooks' 10 | import { stringToBytes, bytesToString } from 'convert-string'; 11 | import * as encoding from 'text-encoding'; 12 | import { 13 | NativeEventEmitter, 14 | NativeModules, 15 | PermissionsAndroid, 16 | Platform, 17 | View, 18 | SafeAreaView 19 | } from 'react-native'; 20 | 21 | import loadLocalResource from 'react-native-local-resource' 22 | import stubbedCode from './stubbed.py' 23 | import BleManager from 'react-native-ble-manager'; 24 | const BleManagerModule = NativeModules.BleManager; 25 | const bleManagerEmitter = new NativeEventEmitter(BleManagerModule); 26 | import RNFS from 'react-native-fs' 27 | 28 | export default function StubbedApp() { 29 | const scheme = useColorScheme(); 30 | var dark = false; 31 | if (scheme == 'dark'){ 32 | dark = true; 33 | } 34 | const currentAppState = useAppState(); 35 | const [isLoading, setIsLoading] = useState("loading"); 36 | const [code, setCode] = useState(""); 37 | 38 | 39 | loadLocalResource(stubbedCode).then((stubbedCodeContent) => { 40 | console.log("stubbed was loaded: " + stubbedCodeContent) 41 | setCode(stubbedCodeContent) 42 | setIsLoading("loaded") 43 | 44 | } 45 | ) 46 | 47 | function changeCode(props) { 48 | var oldCode = code; 49 | console.log(props) 50 | var newCode = oldCode.substring(0,props.offset) + props.newValue + oldCode.substring(props.offset+props.oldValue.length,oldCode.length); 51 | console.log("new code" + newCode) 52 | //// TODO: write newCode to stubbed.py and then run setCode(newCode after) 53 | } 54 | return ( 55 | 56 | 57 | ( 62 | 63 | 64 | 65 | setSearch(search)} 78 | underlineColorAndroid="black" 79 | placeholder="Search through the code ..." 80 | placeholderTextColor={scheme === 'dark' ? 'white' : 'rgb(18,18,18)'} 81 | keyboardType="default" 82 | clearButtonMode="while-editing" 83 | /> 84 | 85 | 93 | )} 94 | 95 | 96 | /> 97 | 98 | 99 | ); 100 | 101 | } 102 | -------------------------------------------------------------------------------- /__tests__/App-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import 'react-native'; 6 | import React from 'react'; 7 | import App from '../App'; 8 | 9 | // Note: test renderer must be required after react-native. 10 | import renderer from 'react-test-renderer'; 11 | 12 | it('renders correctly', () => { 13 | renderer.create(); 14 | }); 15 | -------------------------------------------------------------------------------- /android/app/BUCK: -------------------------------------------------------------------------------- 1 | # To learn about Buck see [Docs](https://buckbuild.com/). 2 | # To run your application with Buck: 3 | # - install Buck 4 | # - `npm start` - to start the packager 5 | # - `cd android` 6 | # - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"` 7 | # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck 8 | # - `buck install -r android/app` - compile, install and run application 9 | # 10 | 11 | load(":build_defs.bzl", "create_aar_targets", "create_jar_targets") 12 | 13 | lib_deps = [] 14 | 15 | create_aar_targets(glob(["libs/*.aar"])) 16 | 17 | create_jar_targets(glob(["libs/*.jar"])) 18 | 19 | android_library( 20 | name = "all-libs", 21 | exported_deps = lib_deps, 22 | ) 23 | 24 | android_library( 25 | name = "app-code", 26 | srcs = glob([ 27 | "src/main/java/**/*.java", 28 | ]), 29 | deps = [ 30 | ":all-libs", 31 | ":build_config", 32 | ":res", 33 | ], 34 | ) 35 | 36 | android_build_config( 37 | name = "build_config", 38 | package = "com.glider", 39 | ) 40 | 41 | android_resource( 42 | name = "res", 43 | package = "com.glider", 44 | res = "src/main/res", 45 | ) 46 | 47 | android_binary( 48 | name = "app", 49 | keystore = "//android/keystores:debug", 50 | manifest = "src/main/AndroidManifest.xml", 51 | package_type = "debug", 52 | deps = [ 53 | ":app-code", 54 | ], 55 | ) 56 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.application" 2 | 3 | import com.android.build.OutputFile 4 | 5 | /** 6 | * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets 7 | * and bundleReleaseJsAndAssets). 8 | * These basically call `react-native bundle` with the correct arguments during the Android build 9 | * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the 10 | * bundle directly from the development server. Below you can see all the possible configurations 11 | * and their defaults. If you decide to add a configuration block, make sure to add it before the 12 | * `apply from: "../../node_modules/react-native/react.gradle"` line. 13 | * 14 | * project.ext.react = [ 15 | * // the name of the generated asset file containing your JS bundle 16 | * bundleAssetName: "index.android.bundle", 17 | * 18 | * // the entry file for bundle generation 19 | * entryFile: "index.android.js", 20 | * 21 | * // https://facebook.github.io/react-native/docs/performance#enable-the-ram-format 22 | * bundleCommand: "ram-bundle", 23 | * 24 | * // whether to bundle JS and assets in debug mode 25 | * bundleInDebug: false, 26 | * 27 | * // whether to bundle JS and assets in release mode 28 | * bundleInRelease: true, 29 | * 30 | * // whether to bundle JS and assets in another build variant (if configured). 31 | * // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants 32 | * // The configuration property can be in the following formats 33 | * // 'bundleIn${productFlavor}${buildType}' 34 | * // 'bundleIn${buildType}' 35 | * // bundleInFreeDebug: true, 36 | * // bundleInPaidRelease: true, 37 | * // bundleInBeta: true, 38 | * 39 | * // whether to disable dev mode in custom build variants (by default only disabled in release) 40 | * // for example: to disable dev mode in the staging build type (if configured) 41 | * devDisabledInStaging: true, 42 | * // The configuration property can be in the following formats 43 | * // 'devDisabledIn${productFlavor}${buildType}' 44 | * // 'devDisabledIn${buildType}' 45 | * 46 | * // the root of your project, i.e. where "package.json" lives 47 | * root: "../../", 48 | * 49 | * // where to put the JS bundle asset in debug mode 50 | * jsBundleDirDebug: "$buildDir/intermediates/assets/debug", 51 | * 52 | * // where to put the JS bundle asset in release mode 53 | * jsBundleDirRelease: "$buildDir/intermediates/assets/release", 54 | * 55 | * // where to put drawable resources / React Native assets, e.g. the ones you use via 56 | * // require('./image.png')), in debug mode 57 | * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug", 58 | * 59 | * // where to put drawable resources / React Native assets, e.g. the ones you use via 60 | * // require('./image.png')), in release mode 61 | * resourcesDirRelease: "$buildDir/intermediates/res/merged/release", 62 | * 63 | * // by default the gradle tasks are skipped if none of the JS files or assets change; this means 64 | * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to 65 | * // date; if you have any other folders that you want to ignore for performance reasons (gradle 66 | * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/ 67 | * // for example, you might want to remove it from here. 68 | * inputExcludes: ["android/**", "ios/**"], 69 | * 70 | * // override which node gets called and with what additional arguments 71 | * nodeExecutableAndArgs: ["node"], 72 | * 73 | * // supply additional arguments to the packager 74 | * extraPackagerArgs: [] 75 | * ] 76 | */ 77 | 78 | project.ext.react = [ 79 | entryFile: "index.js", 80 | enableHermes: false, // clean and rebuild if changing 81 | ] 82 | 83 | apply from: "../../node_modules/react-native/react.gradle" 84 | 85 | /** 86 | * Set this to true to create two separate APKs instead of one: 87 | * - An APK that only works on ARM devices 88 | * - An APK that only works on x86 devices 89 | * The advantage is the size of the APK is reduced by about 4MB. 90 | * Upload all the APKs to the Play Store and people will download 91 | * the correct one based on the CPU architecture of their device. 92 | */ 93 | def enableSeparateBuildPerCPUArchitecture = false 94 | 95 | /** 96 | * Run Proguard to shrink the Java bytecode in release builds. 97 | */ 98 | def enableProguardInReleaseBuilds = false 99 | 100 | /** 101 | * The preferred build flavor of JavaScriptCore. 102 | * 103 | * For example, to use the international variant, you can use: 104 | * `def jscFlavor = 'org.webkit:android-jsc-intl:+'` 105 | * 106 | * The international variant includes ICU i18n library and necessary data 107 | * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that 108 | * give correct results when using with locales other than en-US. Note that 109 | * this variant is about 6MiB larger per architecture than default. 110 | */ 111 | def jscFlavor = 'org.webkit:android-jsc:+' 112 | 113 | /** 114 | * Whether to enable the Hermes VM. 115 | * 116 | * This should be set on project.ext.react and mirrored here. If it is not set 117 | * on project.ext.react, JavaScript will not be compiled to Hermes Bytecode 118 | * and the benefits of using Hermes will therefore be sharply reduced. 119 | */ 120 | def enableHermes = project.ext.react.get("enableHermes", false); 121 | 122 | android { 123 | compileSdkVersion rootProject.ext.compileSdkVersion 124 | 125 | compileOptions { 126 | sourceCompatibility JavaVersion.VERSION_1_8 127 | targetCompatibility JavaVersion.VERSION_1_8 128 | } 129 | 130 | defaultConfig { 131 | applicationId "com.glider" 132 | minSdkVersion rootProject.ext.minSdkVersion 133 | targetSdkVersion rootProject.ext.targetSdkVersion 134 | versionCode 1 135 | versionName "1.0" 136 | } 137 | splits { 138 | abi { 139 | reset() 140 | enable enableSeparateBuildPerCPUArchitecture 141 | universalApk false // If true, also generate a universal APK 142 | include "armeabi-v7a", "x86", "arm64-v8a", "x86_64" 143 | } 144 | } 145 | signingConfigs { 146 | debug { 147 | storeFile file('debug.keystore') 148 | storePassword 'android' 149 | keyAlias 'androiddebugkey' 150 | keyPassword 'android' 151 | } 152 | } 153 | buildTypes { 154 | debug { 155 | signingConfig signingConfigs.debug 156 | } 157 | release { 158 | // Caution! In production, you need to generate your own keystore file. 159 | // see https://facebook.github.io/react-native/docs/signed-apk-android. 160 | signingConfig signingConfigs.debug 161 | minifyEnabled enableProguardInReleaseBuilds 162 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 163 | } 164 | } 165 | // applicationVariants are e.g. debug, release 166 | applicationVariants.all { variant -> 167 | variant.outputs.each { output -> 168 | // For each separate APK per architecture, set a unique version code as described here: 169 | // https://developer.android.com/studio/build/configure-apk-splits.html 170 | def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4] 171 | def abi = output.getFilter(OutputFile.ABI) 172 | if (abi != null) { // null for the universal-debug, universal-release variants 173 | output.versionCodeOverride = 174 | versionCodes.get(abi) * 1048576 + defaultConfig.versionCode 175 | } 176 | 177 | } 178 | } 179 | 180 | packagingOptions { 181 | pickFirst '**/armeabi-v7a/libc++_shared.so' 182 | pickFirst '**/x86/libc++_shared.so' 183 | pickFirst '**/arm64-v8a/libc++_shared.so' 184 | pickFirst '**/x86_64/libc++_shared.so' 185 | pickFirst '**/x86/libjsc.so' 186 | pickFirst '**/armeabi-v7a/libjsc.so' 187 | } 188 | } 189 | 190 | dependencies { 191 | implementation project(':react-native-fs') 192 | implementation project(':react-native-local-resource') 193 | implementation fileTree(dir: "libs", include: ["*.jar"]) 194 | implementation "com.facebook.react:react-native:+" // From node_modules 195 | 196 | if (enableHermes) { 197 | def hermesPath = "../../node_modules/hermesvm/android/"; 198 | debugImplementation files(hermesPath + "hermes-debug.aar") 199 | releaseImplementation files(hermesPath + "hermes-release.aar") 200 | } else { 201 | implementation jscFlavor 202 | } 203 | } 204 | 205 | // Run this once to be able to run the application with BUCK 206 | // puts all compile dependencies into folder libs for BUCK to use 207 | task copyDownloadableDepsToLibs(type: Copy) { 208 | from configurations.compile 209 | into 'libs' 210 | } 211 | 212 | apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) 213 | -------------------------------------------------------------------------------- /android/app/build_defs.bzl: -------------------------------------------------------------------------------- 1 | """Helper definitions to glob .aar and .jar targets""" 2 | 3 | def create_aar_targets(aarfiles): 4 | for aarfile in aarfiles: 5 | name = "aars__" + aarfile[aarfile.rindex("/") + 1:aarfile.rindex(".aar")] 6 | lib_deps.append(":" + name) 7 | android_prebuilt_aar( 8 | name = name, 9 | aar = aarfile, 10 | ) 11 | 12 | def create_jar_targets(jarfiles): 13 | for jarfile in jarfiles: 14 | name = "jars__" + jarfile[jarfile.rindex("/") + 1:jarfile.rindex(".jar")] 15 | lib_deps.append(":" + name) 16 | prebuilt_jar( 17 | name = name, 18 | binary_jar = jarfile, 19 | ) 20 | -------------------------------------------------------------------------------- /android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 12 | 19 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/glider/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.glider; 2 | 3 | import com.facebook.react.ReactActivity; 4 | 5 | public class MainActivity extends ReactActivity { 6 | 7 | /** 8 | * Returns the name of the main component registered from JavaScript. 9 | * This is used to schedule rendering of the component. 10 | */ 11 | @Override 12 | protected String getMainComponentName() { 13 | return "Glider"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/glider/MainApplication.java: -------------------------------------------------------------------------------- 1 | package com.glider; 2 | 3 | import android.app.Application; 4 | import android.util.Log; 5 | 6 | import com.facebook.react.PackageList; 7 | import com.facebook.hermes.reactexecutor.HermesExecutorFactory; 8 | import com.facebook.react.bridge.JavaScriptExecutorFactory; 9 | import com.facebook.react.ReactApplication; 10 | import com.rnfs.RNFSPackage; 11 | import com.igorbelyayev.rnlocalresource.RNLocalResourcePackage; 12 | import com.facebook.react.ReactNativeHost; 13 | import com.facebook.react.ReactPackage; 14 | import com.facebook.soloader.SoLoader; 15 | 16 | import java.util.List; 17 | 18 | public class MainApplication extends Application implements ReactApplication { 19 | 20 | private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { 21 | @Override 22 | public boolean getUseDeveloperSupport() { 23 | return BuildConfig.DEBUG; 24 | } 25 | 26 | @Override 27 | protected List getPackages() { 28 | @SuppressWarnings("UnnecessaryLocalVariable") 29 | List packages = new PackageList(this).getPackages(); 30 | // Packages that cannot be autolinked yet can be added manually here, for example: 31 | // packages.add(new MyReactNativePackage()); 32 | return packages; 33 | } 34 | 35 | @Override 36 | protected String getJSMainModuleName() { 37 | return "index"; 38 | } 39 | }; 40 | 41 | @Override 42 | public ReactNativeHost getReactNativeHost() { 43 | return mReactNativeHost; 44 | } 45 | 46 | @Override 47 | public void onCreate() { 48 | super.onCreate(); 49 | SoLoader.init(this, /* native exopackage */ false); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/glider/e463b130cb19464031fe94904c554743cd353442/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/glider/e463b130cb19464031fe94904c554743cd353442/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/glider/e463b130cb19464031fe94904c554743cd353442/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/glider/e463b130cb19464031fe94904c554743cd353442/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/glider/e463b130cb19464031fe94904c554743cd353442/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/glider/e463b130cb19464031fe94904c554743cd353442/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/glider/e463b130cb19464031fe94904c554743cd353442/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/glider/e463b130cb19464031fe94904c554743cd353442/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/glider/e463b130cb19464031fe94904c554743cd353442/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/glider/e463b130cb19464031fe94904c554743cd353442/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Glider 3 | 4 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | ext { 5 | buildToolsVersion = "28.0.3" 6 | minSdkVersion = 19 7 | compileSdkVersion = 28 8 | targetSdkVersion = 28 9 | supportLibVersion = "28.0.0" 10 | } 11 | repositories { 12 | google() 13 | jcenter() 14 | } 15 | dependencies { 16 | classpath('com.android.tools.build:gradle:3.5.0') 17 | 18 | // NOTE: Do not place your application dependencies here; they belong 19 | // in the individual module build.gradle files 20 | } 21 | } 22 | 23 | allprojects { 24 | repositories { 25 | mavenLocal() 26 | maven { 27 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 28 | url("$rootDir/../node_modules/react-native/android") 29 | } 30 | maven { 31 | // Android JSC is installed from npm 32 | url("$rootDir/../node_modules/jsc-android/dist") 33 | } 34 | 35 | google() 36 | jcenter() 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | android.useAndroidX=true 21 | android.enableJetifier=true 22 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/glider/e463b130cb19464031fe94904c554743cd353442/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /android/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | # Determine the Java command to use to start the JVM. 86 | if [ -n "$JAVA_HOME" ] ; then 87 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 88 | # IBM's JDK on AIX uses strange locations for the executables 89 | JAVACMD="$JAVA_HOME/jre/sh/java" 90 | else 91 | JAVACMD="$JAVA_HOME/bin/java" 92 | fi 93 | if [ ! -x "$JAVACMD" ] ; then 94 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 95 | 96 | Please set the JAVA_HOME variable in your environment to match the 97 | location of your Java installation." 98 | fi 99 | else 100 | JAVACMD="java" 101 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 102 | 103 | Please set the JAVA_HOME variable in your environment to match the 104 | location of your Java installation." 105 | fi 106 | 107 | # Increase the maximum file descriptors if we can. 108 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 109 | MAX_FD_LIMIT=`ulimit -H -n` 110 | if [ $? -eq 0 ] ; then 111 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 112 | MAX_FD="$MAX_FD_LIMIT" 113 | fi 114 | ulimit -n $MAX_FD 115 | if [ $? -ne 0 ] ; then 116 | warn "Could not set maximum file descriptor limit: $MAX_FD" 117 | fi 118 | else 119 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 120 | fi 121 | fi 122 | 123 | # For Darwin, add options to specify how the application appears in the dock 124 | if $darwin; then 125 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 126 | fi 127 | 128 | # For Cygwin, switch paths to Windows format before running java 129 | if $cygwin ; then 130 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 131 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 132 | JAVACMD=`cygpath --unix "$JAVACMD"` 133 | 134 | # We build the pattern for arguments to be converted via cygpath 135 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 136 | SEP="" 137 | for dir in $ROOTDIRSRAW ; do 138 | ROOTDIRS="$ROOTDIRS$SEP$dir" 139 | SEP="|" 140 | done 141 | OURCYGPATTERN="(^($ROOTDIRS))" 142 | # Add a user-defined pattern to the cygpath arguments 143 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 144 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 145 | fi 146 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 147 | i=0 148 | for arg in "$@" ; do 149 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 150 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 151 | 152 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 153 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 154 | else 155 | eval `echo args$i`="\"$arg\"" 156 | fi 157 | i=$((i+1)) 158 | done 159 | case $i in 160 | (0) set -- ;; 161 | (1) set -- "$args0" ;; 162 | (2) set -- "$args0" "$args1" ;; 163 | (3) set -- "$args0" "$args1" "$args2" ;; 164 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 165 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 166 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 167 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 168 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 169 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 170 | esac 171 | fi 172 | 173 | # Escape application args 174 | save () { 175 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 176 | echo " " 177 | } 178 | APP_ARGS=$(save "$@") 179 | 180 | # Collect all arguments for the java command, following the shell quoting and substitution rules 181 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 182 | 183 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 184 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 185 | cd "$(dirname "$0")" 186 | fi 187 | 188 | exec "$JAVACMD" "$@" 189 | -------------------------------------------------------------------------------- /android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem http://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 33 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 34 | 35 | @rem Find java.exe 36 | if defined JAVA_HOME goto findJavaFromJavaHome 37 | 38 | set JAVA_EXE=java.exe 39 | %JAVA_EXE% -version >NUL 2>&1 40 | if "%ERRORLEVEL%" == "0" goto init 41 | 42 | echo. 43 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 44 | echo. 45 | echo Please set the JAVA_HOME variable in your environment to match the 46 | echo location of your Java installation. 47 | 48 | goto fail 49 | 50 | :findJavaFromJavaHome 51 | set JAVA_HOME=%JAVA_HOME:"=% 52 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 53 | 54 | if exist "%JAVA_EXE%" goto init 55 | 56 | echo. 57 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 58 | echo. 59 | echo Please set the JAVA_HOME variable in your environment to match the 60 | echo location of your Java installation. 61 | 62 | goto fail 63 | 64 | :init 65 | @rem Get command-line arguments, handling Windows variants 66 | 67 | if not "%OS%" == "Windows_NT" goto win9xME_args 68 | 69 | :win9xME_args 70 | @rem Slurp the command line arguments. 71 | set CMD_LINE_ARGS= 72 | set _SKIP=2 73 | 74 | :win9xME_args_slurp 75 | if "x%~1" == "x" goto execute 76 | 77 | set CMD_LINE_ARGS=%* 78 | 79 | :execute 80 | @rem Setup the command line 81 | 82 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 83 | 84 | @rem Execute Gradle 85 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 86 | 87 | :end 88 | @rem End local scope for the variables with windows NT shell 89 | if "%ERRORLEVEL%"=="0" goto mainEnd 90 | 91 | :fail 92 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 93 | rem the _cmd.exe /c_ return code! 94 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 95 | exit /b 1 96 | 97 | :mainEnd 98 | if "%OS%"=="Windows_NT" endlocal 99 | 100 | :omega 101 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'Glider' 2 | include ':react-native-fs' 3 | project(':react-native-fs').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-fs/android') 4 | include ':react-native-local-resource' 5 | project(':react-native-local-resource').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-local-resource/android') 6 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) 7 | include ':app' 8 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Glider", 3 | "displayName": "Glider" 4 | } -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | const rnb_preset = require('metro-react-native-babel-preset'); 2 | module.exports = (babel) => { 3 | babel.cache.forever(); 4 | preset = rnb_preset.getPreset(null); 5 | // Patch the preset to allow namespaces. 6 | let typescript_plugins = preset.overrides[2].plugins; 7 | typescript_plugins[0][1].allowNamespaces = true; 8 | // Prepend the const-enum plugin to strip them before the transform. 9 | typescript_plugins.unshift(["const-enum", {}]); 10 | return preset; 11 | }; 12 | -------------------------------------------------------------------------------- /draggable-view.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import { 3 | StyleSheet, 4 | TouchableHighlight, 5 | View, 6 | Animated, 7 | PanResponder, 8 | Dimensions 9 | } from "react-native"; 10 | import PropTypes from "prop-types"; 11 | 12 | class DraggableView extends Component { 13 | 14 | constructor(props) { 15 | super(props); 16 | const initialUsedSpace = Math.abs(this.props.initialDrawerSize); 17 | const initialPosition = initialUsedSpace - Dimensions.get("window").height; 18 | const finalPosition = 0; 19 | if (!props.isInverseDirection) { 20 | initialPosition = Dimensions.get("window").height - initialUsedSpace; 21 | } 22 | 23 | 24 | console.log("initial size", initialPosition); 25 | 26 | this.state = { 27 | touched: false, 28 | position: new Animated.Value(initialPosition), 29 | initialPositon: initialPosition, 30 | finalPosition: finalPosition, 31 | closedPosition: initialPosition, 32 | openPosition: 0, 33 | initialUsedSpace: initialUsedSpace 34 | }; 35 | this._panGesture = PanResponder.create({ 36 | onMoveShouldSetPanResponder: (evt, gestureState) => { 37 | return ( 38 | this.isAValidMovement(gestureState.dx, gestureState.dy) && 39 | this.state.touched 40 | ); 41 | }, 42 | onPanResponderMove: (evt, gestureState) => { 43 | this.moveDrawerView(gestureState); 44 | }, 45 | onPanResponderRelease: (evt, gestureState) => { 46 | this.moveFinished(gestureState); 47 | } 48 | }); 49 | } 50 | 51 | isAValidMovement = (distanceX, distanceY) => { 52 | const moveTravelledFarEnough = 53 | Math.abs(distanceY) > Math.abs(distanceX) && Math.abs(distanceY) > 2; 54 | return moveTravelledFarEnough; 55 | }; 56 | 57 | 58 | startAnimation = ( 59 | velocityY, 60 | positionY, 61 | initialPositon, 62 | id, 63 | finalPosition 64 | ) => { 65 | const { isInverseDirection } = this.props; 66 | 67 | var isGoingToUp = velocityY < 0 ? !isInverseDirection : isInverseDirection; 68 | var endPosition = isGoingToUp ? finalPosition + 50 : initialPositon + 50; 69 | 70 | var position = new Animated.Value(positionY); 71 | position.removeAllListeners(); 72 | 73 | Animated.timing(position, { 74 | toValue: endPosition, 75 | tension: 30, 76 | friction: 0, 77 | velocity: velocityY 78 | }).start(); 79 | 80 | position.addListener(position => { 81 | if (!this.center) return; 82 | this.onUpdatePosition(position.value); 83 | }); 84 | }; 85 | 86 | onUpdatePosition(position) { 87 | position = position - 50; 88 | this.state.position.setValue(position); 89 | this._previousTop = position; 90 | const { initialPosition } = this.state; 91 | 92 | if (initialPosition === position) { 93 | this.props.onInitialPositionReached(); 94 | } 95 | } 96 | 97 | moveDrawerView(gestureState) { 98 | if (!this.center) return; 99 | const position = gestureState.moveY - Dimensions.get("window").height * 0.05; 100 | this.onUpdatePosition(position); 101 | } 102 | 103 | moveFinished(gestureState) { 104 | const isGoingToUp = gestureState.vy < 0; 105 | if (!this.center) return; 106 | this.startAnimation( 107 | gestureState.vy, 108 | gestureState.moveY, 109 | this.state.closedPosition, 110 | gestureState.stateId, 111 | this.state.openPosition 112 | ); 113 | this.props.onRelease(isGoingToUp); 114 | } 115 | 116 | onDrawerLayout(e) { 117 | let drawerHeight = e.nativeEvent.layout.height; 118 | let windowHeight = Dimensions.get("window").height; 119 | this.state.closedPosition = drawerHeight - windowHeight; 120 | this.state.openPosition = 0; 121 | } 122 | 123 | render() { 124 | 125 | const containerView = this.props.renderContainerView(); 126 | const drawerView = this.props.renderDrawerView(); 127 | const initDrawerView = this.props.renderInitDrawerView(); 128 | var bgColor = this.props.bgColor; 129 | const drawerPosition = { 130 | top: this.state.position 131 | }; 132 | //console.log(drawerPosition, Dimensions.get("window")); 133 | 134 | 135 | return ( 136 | 137 | {containerView} 138 | (this.center = center)} 148 | {...this._panGesture.panHandlers} 149 | > 150 | 151 | {drawerView} 152 | 153 | 154 | {initDrawerView 155 | ? ( 156 | this.onDrawerLayout(e)} 158 | //style={this.state.touched? styles.red : styles.blue } 159 | onPressIn={() => this.setState({ touched: true })} 160 | onPressOut={() => this.setState({ touched: false })} 161 | > 162 | {initDrawerView} 163 | 164 | ) 165 | : null 166 | } 167 | 168 | 169 | ); 170 | } 171 | } 172 | 173 | var styles = StyleSheet.create({ 174 | viewport: { 175 | flex: 1 176 | }, 177 | drawer: { 178 | flex: 1 179 | }, 180 | container: { 181 | position: "absolute", 182 | top: 0, 183 | left: 0, 184 | bottom: 0, 185 | right: 0 186 | }, 187 | red: { 188 | color: 'red', 189 | }, 190 | blue: { 191 | color: 'blue', 192 | }, 193 | border: { 194 | borderColor: 'blue', 195 | borderWidth: 2, 196 | }, 197 | }); 198 | 199 | DraggableView.propTypes = { 200 | drawerBg: PropTypes.string, 201 | bgColor: PropTypes.string, 202 | finalDrawerHeight: PropTypes.number, 203 | isInverseDirection: PropTypes.bool, 204 | onInitialPositionReached: PropTypes.func, 205 | onRelease: PropTypes.func, 206 | renderContainerView: PropTypes.func, 207 | renderDrawerView: PropTypes.func, 208 | renderInitDrawerView: PropTypes.func, 209 | }; 210 | 211 | DraggableView.defaultProps = { 212 | drawerBg: "white", 213 | finalDrawerHeight: 0, 214 | isInverseDirection: false, 215 | onInitialPositionReached: () => {}, 216 | onRelease: () => {}, 217 | renderContainerView: () => {}, 218 | renderDrawerView: () => {}, 219 | renderInitDrawerView: () => {} 220 | }; 221 | 222 | export default DraggableView; 223 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | import {AppRegistry} from 'react-native'; 5 | import App from './App'; 6 | import StubbedApp from './StubbedApp' 7 | import {name as appName} from './app.json'; 8 | 9 | const readFromFile = false; 10 | if (readFromFile){ 11 | AppRegistry.registerComponent(appName, () => StubbedApp); 12 | } else { 13 | AppRegistry.registerComponent(appName, () => App); 14 | } 15 | -------------------------------------------------------------------------------- /ios/Glider-tvOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | NSAppTransportSecurity 26 | 27 | NSExceptionDomains 28 | 29 | localhost 30 | 31 | NSExceptionAllowsInsecureHTTPLoads 32 | 33 | 34 | 35 | 36 | NSLocationWhenInUseUsageDescription 37 | 38 | UILaunchStoryboardName 39 | LaunchScreen 40 | UIRequiredDeviceCapabilities 41 | 42 | armv7 43 | 44 | UISupportedInterfaceOrientations 45 | 46 | UIInterfaceOrientationPortrait 47 | UIInterfaceOrientationLandscapeLeft 48 | UIInterfaceOrientationLandscapeRight 49 | 50 | UIViewControllerBasedStatusBarAppearance 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /ios/Glider-tvOSTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /ios/Glider.xcodeproj/xcshareddata/xcschemes/Glider-tvOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 43 | 49 | 50 | 51 | 52 | 53 | 58 | 59 | 61 | 67 | 68 | 69 | 70 | 71 | 77 | 78 | 79 | 80 | 81 | 82 | 92 | 94 | 100 | 101 | 102 | 103 | 104 | 105 | 111 | 113 | 119 | 120 | 121 | 122 | 124 | 125 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /ios/Glider.xcodeproj/xcshareddata/xcschemes/Glider.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 43 | 49 | 50 | 51 | 52 | 53 | 58 | 59 | 61 | 67 | 68 | 69 | 70 | 71 | 77 | 78 | 79 | 80 | 81 | 82 | 92 | 94 | 100 | 101 | 102 | 103 | 104 | 105 | 111 | 113 | 119 | 120 | 121 | 122 | 124 | 125 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /ios/Glider.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/Glider.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Glider/AppDelegate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (nonatomic, strong) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /ios/Glider/AppDelegate.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "AppDelegate.h" 9 | 10 | #import 11 | #import 12 | #import 13 | 14 | @implementation AppDelegate 15 | 16 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 17 | { 18 | RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions]; 19 | RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge 20 | moduleName:@"Glider" 21 | initialProperties:nil]; 22 | 23 | rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; 24 | 25 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 26 | UIViewController *rootViewController = [UIViewController new]; 27 | rootViewController.view = rootView; 28 | self.window.rootViewController = rootViewController; 29 | [self.window makeKeyAndVisible]; 30 | return YES; 31 | } 32 | 33 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge 34 | { 35 | #if DEBUG 36 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; 37 | #else 38 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 39 | #endif 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /ios/Glider/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 21 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /ios/Glider/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ios-marketing", 45 | "scale" : "1x", 46 | "size" : "1024x1024" 47 | } 48 | ], 49 | "info" : { 50 | "author" : "xcode", 51 | "version" : 1 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /ios/Glider/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ios/Glider/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | Glider 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSRequiresIPhoneOS 26 | 27 | NSAppTransportSecurity 28 | 29 | NSAllowsArbitraryLoads 30 | 31 | NSExceptionDomains 32 | 33 | localhost 34 | 35 | NSExceptionAllowsInsecureHTTPLoads 36 | 37 | 38 | 39 | 40 | NSBluetoothAlwaysUsageDescription 41 | We need this to connect to the hardware. 42 | NSLocationWhenInUseUsageDescription 43 | 44 | UIAppFonts 45 | 46 | MaterialCommunityIcons.ttf 47 | MaterialIcons.ttf 48 | 49 | UILaunchStoryboardName 50 | LaunchScreen 51 | UIRequiredDeviceCapabilities 52 | 53 | armv7 54 | 55 | UISupportedInterfaceOrientations 56 | 57 | UIInterfaceOrientationPortrait 58 | UIInterfaceOrientationLandscapeLeft 59 | UIInterfaceOrientationLandscapeRight 60 | 61 | UIViewControllerBasedStatusBarAppearance 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /ios/Glider/main.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import 9 | 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ios/GliderTests/GliderTests.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import 9 | #import 10 | 11 | #import 12 | #import 13 | 14 | #define TIMEOUT_SECONDS 600 15 | #define TEXT_TO_LOOK_FOR @"Welcome to React Native!" 16 | 17 | @interface GliderTests : XCTestCase 18 | 19 | @end 20 | 21 | @implementation GliderTests 22 | 23 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test 24 | { 25 | if (test(view)) { 26 | return YES; 27 | } 28 | for (UIView *subview in [view subviews]) { 29 | if ([self findSubviewInView:subview matching:test]) { 30 | return YES; 31 | } 32 | } 33 | return NO; 34 | } 35 | 36 | - (void)testRendersWelcomeScreen 37 | { 38 | UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController]; 39 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; 40 | BOOL foundElement = NO; 41 | 42 | __block NSString *redboxError = nil; 43 | RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { 44 | if (level >= RCTLogLevelError) { 45 | redboxError = message; 46 | } 47 | }); 48 | 49 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { 50 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 51 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 52 | 53 | foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) { 54 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { 55 | return YES; 56 | } 57 | return NO; 58 | }]; 59 | } 60 | 61 | RCTSetLogFunction(RCTDefaultLogFunction); 62 | 63 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); 64 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); 65 | } 66 | 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /ios/GliderTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /ios/Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '9.0' 2 | require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' 3 | 4 | target 'Glider' do 5 | # Pods for Glider 6 | pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector" 7 | pod 'FBReactNativeSpec', :path => "../node_modules/react-native/Libraries/FBReactNativeSpec" 8 | pod 'RCTRequired', :path => "../node_modules/react-native/Libraries/RCTRequired" 9 | pod 'RCTTypeSafety', :path => "../node_modules/react-native/Libraries/TypeSafety" 10 | pod 'React', :path => '../node_modules/react-native/' 11 | pod 'React-Core', :path => '../node_modules/react-native/' 12 | pod 'React-CoreModules', :path => '../node_modules/react-native/React/CoreModules' 13 | pod 'React-Core/DevSupport', :path => '../node_modules/react-native/' 14 | pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS' 15 | pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation' 16 | pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob' 17 | pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image' 18 | pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS' 19 | pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network' 20 | pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings' 21 | pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text' 22 | pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration' 23 | pod 'React-Core/RCTWebSocket', :path => '../node_modules/react-native/' 24 | 25 | pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact' 26 | pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi' 27 | pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor' 28 | pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector' 29 | pod 'ReactCommon/jscallinvoker', :path => "../node_modules/react-native/ReactCommon" 30 | pod 'ReactCommon/turbomodule/core', :path => "../node_modules/react-native/ReactCommon" 31 | pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga' 32 | 33 | pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec' 34 | pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec' 35 | pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec' 36 | 37 | pod 'react-native-ble-manager', :path => '../node_modules/react-native-ble-manager' 38 | 39 | pod 'RNFS', :path => '../node_modules/react-native-fs' 40 | 41 | target 'GliderTests' do 42 | inherit! :search_paths 43 | # Pods for testing 44 | end 45 | 46 | use_native_modules! 47 | end 48 | 49 | target 'Glider-tvOS' do 50 | # Pods for Glider-tvOS 51 | 52 | target 'Glider-tvOSTests' do 53 | inherit! :search_paths 54 | # Pods for testing 55 | end 56 | 57 | end 58 | -------------------------------------------------------------------------------- /ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - boost-for-react-native (1.63.0) 3 | - DoubleConversion (1.1.6) 4 | - FBLazyVector (0.61.1) 5 | - FBReactNativeSpec (0.61.1): 6 | - Folly (= 2018.10.22.00) 7 | - RCTRequired (= 0.61.1) 8 | - RCTTypeSafety (= 0.61.1) 9 | - React-Core (= 0.61.1) 10 | - React-jsi (= 0.61.1) 11 | - ReactCommon/turbomodule/core (= 0.61.1) 12 | - Folly (2018.10.22.00): 13 | - boost-for-react-native 14 | - DoubleConversion 15 | - Folly/Default (= 2018.10.22.00) 16 | - glog 17 | - Folly/Default (2018.10.22.00): 18 | - boost-for-react-native 19 | - DoubleConversion 20 | - glog 21 | - glog (0.3.5) 22 | - RCTRequired (0.61.1) 23 | - RCTTypeSafety (0.61.1): 24 | - FBLazyVector (= 0.61.1) 25 | - Folly (= 2018.10.22.00) 26 | - RCTRequired (= 0.61.1) 27 | - React-Core (= 0.61.1) 28 | - React (0.61.1): 29 | - React-Core (= 0.61.1) 30 | - React-Core/DevSupport (= 0.61.1) 31 | - React-Core/RCTWebSocket (= 0.61.1) 32 | - React-RCTActionSheet (= 0.61.1) 33 | - React-RCTAnimation (= 0.61.1) 34 | - React-RCTBlob (= 0.61.1) 35 | - React-RCTImage (= 0.61.1) 36 | - React-RCTLinking (= 0.61.1) 37 | - React-RCTNetwork (= 0.61.1) 38 | - React-RCTSettings (= 0.61.1) 39 | - React-RCTText (= 0.61.1) 40 | - React-RCTVibration (= 0.61.1) 41 | - React-Core (0.61.1): 42 | - Folly (= 2018.10.22.00) 43 | - glog 44 | - React-Core/Default (= 0.61.1) 45 | - React-cxxreact (= 0.61.1) 46 | - React-jsi (= 0.61.1) 47 | - React-jsiexecutor (= 0.61.1) 48 | - Yoga 49 | - React-Core/CoreModulesHeaders (0.61.1): 50 | - Folly (= 2018.10.22.00) 51 | - glog 52 | - React-Core/Default 53 | - React-cxxreact (= 0.61.1) 54 | - React-jsi (= 0.61.1) 55 | - React-jsiexecutor (= 0.61.1) 56 | - Yoga 57 | - React-Core/Default (0.61.1): 58 | - Folly (= 2018.10.22.00) 59 | - glog 60 | - React-cxxreact (= 0.61.1) 61 | - React-jsi (= 0.61.1) 62 | - React-jsiexecutor (= 0.61.1) 63 | - Yoga 64 | - React-Core/DevSupport (0.61.1): 65 | - Folly (= 2018.10.22.00) 66 | - glog 67 | - React-Core/Default (= 0.61.1) 68 | - React-Core/RCTWebSocket (= 0.61.1) 69 | - React-cxxreact (= 0.61.1) 70 | - React-jsi (= 0.61.1) 71 | - React-jsiexecutor (= 0.61.1) 72 | - React-jsinspector (= 0.61.1) 73 | - Yoga 74 | - React-Core/RCTActionSheetHeaders (0.61.1): 75 | - Folly (= 2018.10.22.00) 76 | - glog 77 | - React-Core/Default 78 | - React-cxxreact (= 0.61.1) 79 | - React-jsi (= 0.61.1) 80 | - React-jsiexecutor (= 0.61.1) 81 | - Yoga 82 | - React-Core/RCTAnimationHeaders (0.61.1): 83 | - Folly (= 2018.10.22.00) 84 | - glog 85 | - React-Core/Default 86 | - React-cxxreact (= 0.61.1) 87 | - React-jsi (= 0.61.1) 88 | - React-jsiexecutor (= 0.61.1) 89 | - Yoga 90 | - React-Core/RCTBlobHeaders (0.61.1): 91 | - Folly (= 2018.10.22.00) 92 | - glog 93 | - React-Core/Default 94 | - React-cxxreact (= 0.61.1) 95 | - React-jsi (= 0.61.1) 96 | - React-jsiexecutor (= 0.61.1) 97 | - Yoga 98 | - React-Core/RCTImageHeaders (0.61.1): 99 | - Folly (= 2018.10.22.00) 100 | - glog 101 | - React-Core/Default 102 | - React-cxxreact (= 0.61.1) 103 | - React-jsi (= 0.61.1) 104 | - React-jsiexecutor (= 0.61.1) 105 | - Yoga 106 | - React-Core/RCTLinkingHeaders (0.61.1): 107 | - Folly (= 2018.10.22.00) 108 | - glog 109 | - React-Core/Default 110 | - React-cxxreact (= 0.61.1) 111 | - React-jsi (= 0.61.1) 112 | - React-jsiexecutor (= 0.61.1) 113 | - Yoga 114 | - React-Core/RCTNetworkHeaders (0.61.1): 115 | - Folly (= 2018.10.22.00) 116 | - glog 117 | - React-Core/Default 118 | - React-cxxreact (= 0.61.1) 119 | - React-jsi (= 0.61.1) 120 | - React-jsiexecutor (= 0.61.1) 121 | - Yoga 122 | - React-Core/RCTSettingsHeaders (0.61.1): 123 | - Folly (= 2018.10.22.00) 124 | - glog 125 | - React-Core/Default 126 | - React-cxxreact (= 0.61.1) 127 | - React-jsi (= 0.61.1) 128 | - React-jsiexecutor (= 0.61.1) 129 | - Yoga 130 | - React-Core/RCTTextHeaders (0.61.1): 131 | - Folly (= 2018.10.22.00) 132 | - glog 133 | - React-Core/Default 134 | - React-cxxreact (= 0.61.1) 135 | - React-jsi (= 0.61.1) 136 | - React-jsiexecutor (= 0.61.1) 137 | - Yoga 138 | - React-Core/RCTVibrationHeaders (0.61.1): 139 | - Folly (= 2018.10.22.00) 140 | - glog 141 | - React-Core/Default 142 | - React-cxxreact (= 0.61.1) 143 | - React-jsi (= 0.61.1) 144 | - React-jsiexecutor (= 0.61.1) 145 | - Yoga 146 | - React-Core/RCTWebSocket (0.61.1): 147 | - Folly (= 2018.10.22.00) 148 | - glog 149 | - React-Core/Default (= 0.61.1) 150 | - React-cxxreact (= 0.61.1) 151 | - React-jsi (= 0.61.1) 152 | - React-jsiexecutor (= 0.61.1) 153 | - Yoga 154 | - React-CoreModules (0.61.1): 155 | - FBReactNativeSpec (= 0.61.1) 156 | - Folly (= 2018.10.22.00) 157 | - RCTTypeSafety (= 0.61.1) 158 | - React-Core/CoreModulesHeaders (= 0.61.1) 159 | - React-RCTImage (= 0.61.1) 160 | - ReactCommon/turbomodule/core (= 0.61.1) 161 | - React-cxxreact (0.61.1): 162 | - boost-for-react-native (= 1.63.0) 163 | - DoubleConversion 164 | - Folly (= 2018.10.22.00) 165 | - glog 166 | - React-jsinspector (= 0.61.1) 167 | - React-jsi (0.61.1): 168 | - boost-for-react-native (= 1.63.0) 169 | - DoubleConversion 170 | - Folly (= 2018.10.22.00) 171 | - glog 172 | - React-jsi/Default (= 0.61.1) 173 | - React-jsi/Default (0.61.1): 174 | - boost-for-react-native (= 1.63.0) 175 | - DoubleConversion 176 | - Folly (= 2018.10.22.00) 177 | - glog 178 | - React-jsiexecutor (0.61.1): 179 | - DoubleConversion 180 | - Folly (= 2018.10.22.00) 181 | - glog 182 | - React-cxxreact (= 0.61.1) 183 | - React-jsi (= 0.61.1) 184 | - React-jsinspector (0.61.1) 185 | - react-native-appearance (0.3.4): 186 | - React 187 | - react-native-ble-manager (6.7.1): 188 | - React 189 | - react-native-safe-area-context (3.0.7): 190 | - React 191 | - React-RCTActionSheet (0.61.1): 192 | - React-Core/RCTActionSheetHeaders (= 0.61.1) 193 | - React-RCTAnimation (0.61.1): 194 | - React-Core/RCTAnimationHeaders (= 0.61.1) 195 | - React-RCTBlob (0.61.1): 196 | - React-Core/RCTBlobHeaders (= 0.61.1) 197 | - React-Core/RCTWebSocket (= 0.61.1) 198 | - React-jsi (= 0.61.1) 199 | - React-RCTNetwork (= 0.61.1) 200 | - React-RCTImage (0.61.1): 201 | - React-Core/RCTImageHeaders (= 0.61.1) 202 | - React-RCTNetwork (= 0.61.1) 203 | - React-RCTLinking (0.61.1): 204 | - React-Core/RCTLinkingHeaders (= 0.61.1) 205 | - React-RCTNetwork (0.61.1): 206 | - React-Core/RCTNetworkHeaders (= 0.61.1) 207 | - React-RCTSettings (0.61.1): 208 | - React-Core/RCTSettingsHeaders (= 0.61.1) 209 | - React-RCTText (0.61.1): 210 | - React-Core/RCTTextHeaders (= 0.61.1) 211 | - React-RCTVibration (0.61.1): 212 | - React-Core/RCTVibrationHeaders (= 0.61.1) 213 | - ReactCommon/jscallinvoker (0.61.1): 214 | - DoubleConversion 215 | - Folly (= 2018.10.22.00) 216 | - glog 217 | - React-cxxreact (= 0.61.1) 218 | - ReactCommon/turbomodule/core (0.61.1): 219 | - DoubleConversion 220 | - Folly (= 2018.10.22.00) 221 | - glog 222 | - React-Core (= 0.61.1) 223 | - React-cxxreact (= 0.61.1) 224 | - React-jsi (= 0.61.1) 225 | - ReactCommon/jscallinvoker (= 0.61.1) 226 | - RNCMaskedView (0.1.10): 227 | - React 228 | - RNFS (2.16.6): 229 | - React 230 | - RNGestureHandler (1.6.1): 231 | - React 232 | - RNReanimated (1.9.0): 233 | - React 234 | - RNScreens (2.9.0): 235 | - React 236 | - RNVectorIcons (7.0.0): 237 | - React 238 | - Yoga (1.14.0) 239 | 240 | DEPENDENCIES: 241 | - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) 242 | - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`) 243 | - FBReactNativeSpec (from `../node_modules/react-native/Libraries/FBReactNativeSpec`) 244 | - Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`) 245 | - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) 246 | - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`) 247 | - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`) 248 | - React (from `../node_modules/react-native/`) 249 | - React-Core (from `../node_modules/react-native/`) 250 | - React-Core/DevSupport (from `../node_modules/react-native/`) 251 | - React-Core/RCTWebSocket (from `../node_modules/react-native/`) 252 | - React-CoreModules (from `../node_modules/react-native/React/CoreModules`) 253 | - React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`) 254 | - React-jsi (from `../node_modules/react-native/ReactCommon/jsi`) 255 | - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`) 256 | - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`) 257 | - react-native-appearance (from `../node_modules/react-native-appearance`) 258 | - react-native-ble-manager (from `../node_modules/react-native-ble-manager`) 259 | - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`) 260 | - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) 261 | - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`) 262 | - React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`) 263 | - React-RCTImage (from `../node_modules/react-native/Libraries/Image`) 264 | - React-RCTLinking (from `../node_modules/react-native/Libraries/LinkingIOS`) 265 | - React-RCTNetwork (from `../node_modules/react-native/Libraries/Network`) 266 | - React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`) 267 | - React-RCTText (from `../node_modules/react-native/Libraries/Text`) 268 | - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`) 269 | - ReactCommon/jscallinvoker (from `../node_modules/react-native/ReactCommon`) 270 | - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) 271 | - "RNCMaskedView (from `../node_modules/@react-native-community/masked-view`)" 272 | - RNFS (from `../node_modules/react-native-fs`) 273 | - RNGestureHandler (from `../node_modules/react-native-gesture-handler`) 274 | - RNReanimated (from `../node_modules/react-native-reanimated`) 275 | - RNScreens (from `../node_modules/react-native-screens`) 276 | - RNVectorIcons (from `../node_modules/react-native-vector-icons`) 277 | - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) 278 | 279 | SPEC REPOS: 280 | trunk: 281 | - boost-for-react-native 282 | 283 | EXTERNAL SOURCES: 284 | DoubleConversion: 285 | :podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec" 286 | FBLazyVector: 287 | :path: "../node_modules/react-native/Libraries/FBLazyVector" 288 | FBReactNativeSpec: 289 | :path: "../node_modules/react-native/Libraries/FBReactNativeSpec" 290 | Folly: 291 | :podspec: "../node_modules/react-native/third-party-podspecs/Folly.podspec" 292 | glog: 293 | :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" 294 | RCTRequired: 295 | :path: "../node_modules/react-native/Libraries/RCTRequired" 296 | RCTTypeSafety: 297 | :path: "../node_modules/react-native/Libraries/TypeSafety" 298 | React: 299 | :path: "../node_modules/react-native/" 300 | React-Core: 301 | :path: "../node_modules/react-native/" 302 | React-CoreModules: 303 | :path: "../node_modules/react-native/React/CoreModules" 304 | React-cxxreact: 305 | :path: "../node_modules/react-native/ReactCommon/cxxreact" 306 | React-jsi: 307 | :path: "../node_modules/react-native/ReactCommon/jsi" 308 | React-jsiexecutor: 309 | :path: "../node_modules/react-native/ReactCommon/jsiexecutor" 310 | React-jsinspector: 311 | :path: "../node_modules/react-native/ReactCommon/jsinspector" 312 | react-native-appearance: 313 | :path: "../node_modules/react-native-appearance" 314 | react-native-ble-manager: 315 | :path: "../node_modules/react-native-ble-manager" 316 | react-native-safe-area-context: 317 | :path: "../node_modules/react-native-safe-area-context" 318 | React-RCTActionSheet: 319 | :path: "../node_modules/react-native/Libraries/ActionSheetIOS" 320 | React-RCTAnimation: 321 | :path: "../node_modules/react-native/Libraries/NativeAnimation" 322 | React-RCTBlob: 323 | :path: "../node_modules/react-native/Libraries/Blob" 324 | React-RCTImage: 325 | :path: "../node_modules/react-native/Libraries/Image" 326 | React-RCTLinking: 327 | :path: "../node_modules/react-native/Libraries/LinkingIOS" 328 | React-RCTNetwork: 329 | :path: "../node_modules/react-native/Libraries/Network" 330 | React-RCTSettings: 331 | :path: "../node_modules/react-native/Libraries/Settings" 332 | React-RCTText: 333 | :path: "../node_modules/react-native/Libraries/Text" 334 | React-RCTVibration: 335 | :path: "../node_modules/react-native/Libraries/Vibration" 336 | ReactCommon: 337 | :path: "../node_modules/react-native/ReactCommon" 338 | RNCMaskedView: 339 | :path: "../node_modules/@react-native-community/masked-view" 340 | RNFS: 341 | :path: "../node_modules/react-native-fs" 342 | RNGestureHandler: 343 | :path: "../node_modules/react-native-gesture-handler" 344 | RNReanimated: 345 | :path: "../node_modules/react-native-reanimated" 346 | RNScreens: 347 | :path: "../node_modules/react-native-screens" 348 | RNVectorIcons: 349 | :path: "../node_modules/react-native-vector-icons" 350 | Yoga: 351 | :path: "../node_modules/react-native/ReactCommon/yoga" 352 | 353 | SPEC CHECKSUMS: 354 | boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c 355 | DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 356 | FBLazyVector: 0846affdb2924b01093eb696766ecb0104e409e0 357 | FBReactNativeSpec: c4cf958af1b97799b524f63a26a1c509c0295b04 358 | Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 359 | glog: 1f3da668190260b06b429bb211bfbee5cd790c28 360 | RCTRequired: 53825815218847d3e9c7b6d92ad2d197a926d51e 361 | RCTTypeSafety: d886540c518e53064dfa081bf7693fd650699b92 362 | React: 5dea58967c421bd1fdf6b94c18b9ed0f5134683c 363 | React-Core: b381e65aa0da9b94b9dcdc4a99298075b1c3876c 364 | React-CoreModules: 4ed224e29848ba76d26aacb8e3fe85712d3c4fe1 365 | React-cxxreact: 52c98f5c1fb4e4d9f4b588742718350a55f4f088 366 | React-jsi: 61ff417c95e6c3af50fb96399037e80752fb5ce7 367 | React-jsiexecutor: ee45274419eb95614bbbadb98e20684c5f29996e 368 | React-jsinspector: 574d597112f9ea3d1b717f6fb62aef764c70dd6f 369 | react-native-appearance: fc2014516054585d531e07aa0b40ab0de1d2be85 370 | react-native-ble-manager: f81d736790c88c2fddb3e10e0df0cf580a52b041 371 | react-native-safe-area-context: c39fc20a20cd66ebf1d56c6f8b8711142fbfee98 372 | React-RCTActionSheet: af4d951113b1e068bb30611f91b984a7a73597ff 373 | React-RCTAnimation: 4f518d70bb6890b7c3d9d732f84786d6693ca297 374 | React-RCTBlob: 072a4888c08de0eef6d04eaa727d25e577e6ff26 375 | React-RCTImage: 78c5cdf1b2de6cd3cd650dd741868fad19a35528 376 | React-RCTLinking: 486ed1c9a659c7f9fea213868f8930b9a0a79f07 377 | React-RCTNetwork: e79599f3160b459da03447e32b8bcca1a0f0f797 378 | React-RCTSettings: 48b7c5a64ffe0c54c39d59eb7d9036e72305f95a 379 | React-RCTText: 81b62b4e7f11531a5154e4daa5617670d5a2d5de 380 | React-RCTVibration: 8be61459e3749d1fb02cf414edd05b3007622882 381 | ReactCommon: 4fba5be89efdf0b5720e0adb3d8d7edf6e532db0 382 | RNCMaskedView: f5c7d14d6847b7b44853f7acb6284c1da30a3459 383 | RNFS: 2bd9eb49dc82fa9676382f0585b992c424cd59df 384 | RNGestureHandler: 8f09cd560f8d533eb36da5a6c5a843af9f056b38 385 | RNReanimated: b5ccb50650ba06f6e749c7c329a1bc3ae0c88b43 386 | RNScreens: c526239bbe0e957b988dacc8d75ac94ec9cb19da 387 | RNVectorIcons: da6fe858f5a65d7bbc3379540a889b0b12aa5976 388 | Yoga: d8c572ddec8d05b7dba08e4e5f1924004a177078 389 | 390 | PODFILE CHECKSUM: 4ea9948c01aa7074373b93278aebd95553fe2ec7 391 | 392 | COCOAPODS: 1.9.3 393 | -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/glider/e463b130cb19464031fe94904c554743cd353442/logo.png -------------------------------------------------------------------------------- /metro.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Metro configuration for React Native 3 | * https://github.com/facebook/react-native 4 | * 5 | * @format 6 | */ 7 | 8 | module.exports = { 9 | transformer: { 10 | getTransformOptions: async () => ({ 11 | transform: { 12 | experimentalImportSupport: false, 13 | inlineRequires: false, 14 | }, 15 | }), 16 | }, 17 | resolver: { 18 | assetExts: ["py"] 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /old-app.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { 3 | AppRegistry, 4 | StyleSheet, 5 | Text, 6 | View, 7 | TouchableHighlight, 8 | NativeAppEventEmitter, 9 | NativeEventEmitter, 10 | NativeModules, 11 | Platform, 12 | PermissionsAndroid, 13 | FlatList, 14 | ScrollView, 15 | AppState, 16 | Dimensions, 17 | } from 'react-native'; 18 | import { stringToBytes, bytesToString } from 'convert-string'; 19 | import BleManager from 'react-native-ble-manager'; 20 | import DraggableView from 'draggable-view'; 21 | 22 | 23 | import { Status, StatusSummary } from 'status'; 24 | 25 | import { CodeEditor } from 'code-editor'; 26 | 27 | const window = Dimensions.get('window'); 28 | 29 | const BleManagerModule = NativeModules.BleManager; 30 | const bleManagerEmitter = new NativeEventEmitter(BleManagerModule); 31 | 32 | export default class App extends Component { 33 | constructor(){ 34 | super() 35 | 36 | this.state = { 37 | scanning:false, 38 | peripherals: new Map(), 39 | appState: '' 40 | } 41 | 42 | this.handleDiscoverPeripheral = this.handleDiscoverPeripheral.bind(this); 43 | this.handleStopScan = this.handleStopScan.bind(this); 44 | this.handleUpdateValueForCharacteristic = this.handleUpdateValueForCharacteristic.bind(this); 45 | this.handleDisconnectedPeripheral = this.handleDisconnectedPeripheral.bind(this); 46 | this.handleAppStateChange = this.handleAppStateChange.bind(this); 47 | } 48 | 49 | componentDidMount() { 50 | AppState.addEventListener('change', this.handleAppStateChange); 51 | 52 | BleManager.start({showAlert: false}); 53 | 54 | this.handlerDiscover = bleManagerEmitter.addListener('BleManagerDiscoverPeripheral', this.handleDiscoverPeripheral ); 55 | this.handlerStop = bleManagerEmitter.addListener('BleManagerStopScan', this.handleStopScan ); 56 | this.handlerDisconnect = bleManagerEmitter.addListener('BleManagerDisconnectPeripheral', this.handleDisconnectedPeripheral ); 57 | this.handlerUpdate = bleManagerEmitter.addListener('BleManagerDidUpdateValueForCharacteristic', this.handleUpdateValueForCharacteristic ); 58 | 59 | 60 | 61 | if (Platform.OS === 'android' && Platform.Version >= 23) { 62 | PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION).then((result) => { 63 | if (result) { 64 | console.log("Permission is OK"); 65 | } else { 66 | PermissionsAndroid.requestPermission(PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION).then((result) => { 67 | if (result) { 68 | console.log("User accept"); 69 | } else { 70 | console.log("User refuse"); 71 | } 72 | }); 73 | } 74 | }); 75 | } 76 | 77 | } 78 | 79 | handleAppStateChange(nextAppState) { 80 | if (this.state.appState.match(/inactive|background/) && nextAppState === 'active') { 81 | console.log('App has come to the foreground!') 82 | BleManager.getConnectedPeripherals([]).then((peripheralsArray) => { 83 | console.log('Connected peripherals: ' + peripheralsArray.length); 84 | }); 85 | } 86 | this.setState({appState: nextAppState}); 87 | } 88 | 89 | componentWillUnmount() { 90 | this.handlerDiscover.remove(); 91 | this.handlerStop.remove(); 92 | this.handlerDisconnect.remove(); 93 | this.handlerUpdate.remove(); 94 | } 95 | 96 | handleDisconnectedPeripheral(data) { 97 | let peripherals = this.state.peripherals; 98 | let peripheral = peripherals.get(data.peripheral); 99 | if (peripheral) { 100 | peripheral.connected = false; 101 | peripherals.set(peripheral.id, peripheral); 102 | this.setState({peripherals}); 103 | } 104 | console.log('Disconnected from ' + data.peripheral); 105 | } 106 | 107 | handleUpdateValueForCharacteristic(data) { 108 | console.log('Received data from ' + data.peripheral + ' characteristic ' + data.characteristic, bytesToString(data.value)); 109 | } 110 | 111 | handleStopScan() { 112 | console.log('Scan is stopped'); 113 | this.setState({ scanning: false }); 114 | } 115 | 116 | startScan() { 117 | if (!this.state.scanning) { 118 | this.setState({peripherals: new Map()}); 119 | BleManager.scan([], 3, true).then((results) => { 120 | console.log('Scanning...'); 121 | this.setState({scanning:true}); 122 | }); 123 | } 124 | } 125 | 126 | retrieveConnected(){ 127 | BleManager.getConnectedPeripherals([]).then((results) => { 128 | if (results.length == 0) { 129 | console.log('No connected peripherals') 130 | } 131 | console.log(results); 132 | var peripherals = this.state.peripherals; 133 | for (var i = 0; i < results.length; i++) { 134 | var peripheral = results[i]; 135 | peripheral.connected = true; 136 | peripherals.set(peripheral.id, peripheral); 137 | this.setState({ peripherals }); 138 | } 139 | }); 140 | } 141 | 142 | handleDiscoverPeripheral(peripheral){ 143 | var peripherals = this.state.peripherals; 144 | if (!peripherals.has(peripheral.id)){ 145 | console.log('Got ble peripheral', peripheral); 146 | peripherals.set(peripheral.id, peripheral); 147 | this.setState({ peripherals }) 148 | } 149 | } 150 | 151 | test(peripheral) { 152 | if (peripheral){ 153 | if (peripheral.connected){ 154 | BleManager.disconnect(peripheral.id); 155 | }else{ 156 | BleManager.connect(peripheral.id).then(() => { 157 | let peripherals = this.state.peripherals; 158 | let p = peripherals.get(peripheral.id); 159 | if (p) { 160 | p.connected = true; 161 | peripherals.set(peripheral.id, p); 162 | this.setState({peripherals}); 163 | } 164 | console.log('Connected to ' + peripheral.id); 165 | 166 | 167 | setTimeout(() => { 168 | 169 | /* Test read current RSSI value 170 | BleManager.retrieveServices(peripheral.id).then((peripheralData) => { 171 | console.log('Retrieved peripheral services', peripheralData); 172 | 173 | BleManager.readRSSI(peripheral.id).then((rssi) => { 174 | console.log('Retrieved actual RSSI value', rssi); 175 | }); 176 | });*/ 177 | 178 | // Test using bleno's pizza example 179 | // https://github.com/sandeepmistry/bleno/tree/master/examples/pizza 180 | BleManager.retrieveServices(peripheral.id).then((peripheralInfo) => { 181 | console.log(peripheralInfo); 182 | var service = 'adaf0100-4369-7263-7569-74507974686e'; 183 | var bakeCharacteristic = 'adaf0201-4369-7263-7569-74507974686e'; 184 | var filenameCharacteristic = 'adaf0200-4369-7263-7569-74507974686e'; 185 | 186 | setTimeout(() => { 187 | BleManager.startNotification(peripheral.id, service, bakeCharacteristic).then(() => { 188 | console.log('Started notification on ' + peripheral.id); 189 | setTimeout(() => { 190 | BleManager.write(peripheral.id, service, filenameCharacteristic, stringToBytes("/code.py")).then(() => { 191 | console.log('Wrote filename'); 192 | }); 193 | 194 | }, 500); 195 | }).catch((error) => { 196 | console.log('Notification error', error); 197 | }); 198 | }, 200); 199 | }); 200 | 201 | }, 900); 202 | }).catch((error) => { 203 | console.log('Connection error', error); 204 | }); 205 | } 206 | } 207 | } 208 | 209 | render() { 210 | return ( ( 213 | )} 214 | renderDrawerView={() => ( 215 | )} 216 | 217 | />); 218 | 219 | // const list = Array.from(this.state.peripherals.values()); 220 | 221 | // return ( 222 | // 223 | // this.startScan() }> 224 | // Scan Bluetooth ({this.state.scanning ? 'on' : 'off'}) 225 | // 226 | // this.retrieveConnected() }> 227 | // Retrieve connected peripherals 228 | // 229 | // 231 | // No peripherals 232 | // } 233 | // enableEmptySections={true} 234 | // data={list} 235 | // renderItem={({item, index, separators}) => { 236 | // const color = item.connected ? 'green' : '#fff'; 237 | // return ( 238 | // this.test(item) }> 239 | // 240 | // name: {item.name} 241 | // id: {item.id} 242 | // 243 | // 244 | // ); 245 | // }} 246 | // /> 247 | // 248 | // ); 249 | } 250 | } 251 | 252 | const styles = StyleSheet.create({ 253 | container: { 254 | flex: 1, 255 | backgroundColor: '#FFF', 256 | width: window.width, 257 | height: window.height 258 | }, 259 | scroll: { 260 | flex: 1, 261 | backgroundColor: '#f0f0f0', 262 | margin: 10, 263 | }, 264 | row: { 265 | margin: 10 266 | }, 267 | }); 268 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Glider", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "start": "react-native start", 7 | "test": "jest", 8 | "lint": "eslint ." 9 | }, 10 | "dependencies": { 11 | "@iomechs/rn-color-palette": "0.0.4", 12 | "@react-native-community/clipboard": "^1.2.3", 13 | "@react-native-community/masked-view": "^0.1.10", 14 | "@react-navigation/native": "^5.6.1", 15 | "@types/jest": "^24.0.18", 16 | "@types/node": "^12.7.7", 17 | "@types/react": "^16.9.3", 18 | "@types/react-dom": "^16.9.1", 19 | "assert": "^2.0.0", 20 | "convert-string": "^0.1.0", 21 | "path": "^0.12.7", 22 | "react": "^16.9.0", 23 | "react-native": "^0.61.1", 24 | "react-native-appearance": "^0.3.4", 25 | "react-native-ble-manager": "^6.6.9", 26 | "react-native-draggable-flatlist": "^2.3.3", 27 | "react-native-elements": "^2.0.4", 28 | "react-native-fs": "^2.16.6", 29 | "react-native-gesture-handler": "^1.6.1", 30 | "react-native-hooks": "^0.9.0", 31 | "react-native-local-resource": "^0.1.6", 32 | "react-native-reanimated": "^1.9.0", 33 | "react-native-safe-area-context": "^3.0.7", 34 | "react-native-screens": "^2.9.0", 35 | "react-native-swipeout": "^2.3.6", 36 | "react-native-vector-icons": "^7.0.0", 37 | "text-encoding": "^0.7.0", 38 | "tsutils": "^3.17.1", 39 | "typescript": "^3.6.3" 40 | }, 41 | "devDependencies": { 42 | "@babel/core": "^7.6.2", 43 | "@babel/runtime": "^7.6.2", 44 | "@react-native-community/eslint-config": "^0.0.5", 45 | "babel-jest": "^24.9.0", 46 | "babel-plugin-const-enum": "0.0.2", 47 | "eslint": "^5.16.0", 48 | "jest": "^24.9.0", 49 | "metro-react-native-babel-preset": "^0.56.0", 50 | "react-test-renderer": "16.8.6" 51 | }, 52 | "jest": { 53 | "preset": "react-native" 54 | }, 55 | "main": "index.js", 56 | "author": "Scott Shawcroft ", 57 | "license": "MIT" 58 | } 59 | -------------------------------------------------------------------------------- /status.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | StyleSheet, Text, View} from 'react-native'; 4 | 5 | export default function Status(props) { 6 | 7 | return ( 8 | Status 9 | ); 10 | } 11 | 12 | export function StatusSummary(props) { 13 | return ( 14 | {props.bleState} 16 | ); 17 | } 18 | 19 | var styles = StyleSheet.create({ 20 | viewport: { 21 | flex: 1 22 | }, 23 | drawer: { 24 | flex: 1 25 | }, 26 | container: { 27 | position: "absolute", 28 | top: 0, 29 | left: 0, 30 | bottom: 0, 31 | right: 0 32 | }, 33 | red: { 34 | color: 'red', 35 | }, 36 | }); -------------------------------------------------------------------------------- /stubbed.py: -------------------------------------------------------------------------------- 1 | import board 2 | import digitalio 3 | import time 4 | 5 | led = digitalio.DigitalInOut(board.D13) 6 | led.direction = digitalio.Direction.OUTPUT 7 | 8 | while True: 9 | led.value = True 10 | time.sleep(0.5) 11 | led.value = False 12 | time.sleep(0.5) 13 | time.sleep(.4444) 14 | -------------------------------------------------------------------------------- /template.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | placeholderName: 'Glider', 3 | templateDir: './template', 4 | } 5 | -------------------------------------------------------------------------------- /template/.buckconfig: -------------------------------------------------------------------------------- 1 | 2 | [android] 3 | target = Google Inc.:Google APIs:23 4 | 5 | [maven_repositories] 6 | central = https://repo1.maven.org/maven2 7 | -------------------------------------------------------------------------------- /template/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: '@react-native-community', 4 | }; 5 | -------------------------------------------------------------------------------- /template/.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | -------------------------------------------------------------------------------- /template/.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 | project.xcworkspace 24 | 25 | # Android/IntelliJ 26 | # 27 | build/ 28 | .idea 29 | .gradle 30 | local.properties 31 | *.iml 32 | 33 | # Visual Studio Code 34 | # 35 | .vscode/ 36 | 37 | # node.js 38 | # 39 | node_modules/ 40 | npm-debug.log 41 | yarn-error.log 42 | 43 | # BUCK 44 | buck-out/ 45 | \.buckd/ 46 | *.keystore 47 | 48 | # fastlane 49 | # 50 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 51 | # screenshots whenever they are needed. 52 | # For more information about the recommended setup visit: 53 | # https://docs.fastlane.tools/best-practices/source-control/ 54 | 55 | */fastlane/report.xml 56 | */fastlane/Preview.html 57 | */fastlane/screenshots 58 | 59 | # Bundle artifact 60 | *.jsbundle 61 | 62 | # CocoaPods 63 | /ios/Pods/ 64 | -------------------------------------------------------------------------------- /template/.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | bracketSpacing: false, 3 | jsxBracketSameLine: true, 4 | singleQuote: true, 5 | trailingComma: 'all', 6 | }; 7 | -------------------------------------------------------------------------------- /template/.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /template/App.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Sample React Native App 3 | * https://github.com/facebook/react-native 4 | * 5 | * Generated with the TypeScript template 6 | * https://github.com/react-native-community/react-native-template-typescript 7 | * 8 | * @format 9 | */ 10 | 11 | import React, {Fragment} from 'react'; 12 | import { 13 | SafeAreaView, 14 | StyleSheet, 15 | ScrollView, 16 | View, 17 | Text, 18 | StatusBar, 19 | } from 'react-native'; 20 | 21 | import { 22 | Header, 23 | LearnMoreLinks, 24 | Colors, 25 | DebugInstructions, 26 | ReloadInstructions, 27 | } from 'react-native/Libraries/NewAppScreen'; 28 | 29 | const App = () => { 30 | return ( 31 | 32 | 33 | 34 | 37 |
38 | {global.HermesInternal == null ? null : ( 39 | 40 | Engine: Hermes 41 | 42 | )} 43 | 44 | 45 | Step One 46 | 47 | Edit App.tsx to change this 48 | screen and then come back to see your edits. 49 | 50 | 51 | 52 | See Your Changes 53 | 54 | 55 | 56 | 57 | 58 | Debug 59 | 60 | 61 | 62 | 63 | 64 | Learn More 65 | 66 | Read the docs to discover what to do next: 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | ); 75 | }; 76 | 77 | const styles = StyleSheet.create({ 78 | scrollView: { 79 | backgroundColor: Colors.lighter, 80 | }, 81 | engine: { 82 | position: 'absolute', 83 | right: 0, 84 | }, 85 | body: { 86 | backgroundColor: Colors.white, 87 | }, 88 | sectionContainer: { 89 | marginTop: 32, 90 | paddingHorizontal: 24, 91 | }, 92 | sectionTitle: { 93 | fontSize: 24, 94 | fontWeight: '600', 95 | color: Colors.black, 96 | }, 97 | sectionDescription: { 98 | marginTop: 8, 99 | fontSize: 18, 100 | fontWeight: '400', 101 | color: Colors.dark, 102 | }, 103 | highlight: { 104 | fontWeight: '700', 105 | }, 106 | footer: { 107 | color: Colors.dark, 108 | fontSize: 12, 109 | fontWeight: '600', 110 | padding: 4, 111 | paddingRight: 12, 112 | textAlign: 'right', 113 | }, 114 | }); 115 | 116 | export default App; 117 | -------------------------------------------------------------------------------- /template/__tests__/App-test.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import 'react-native'; 6 | import React from 'react'; 7 | import App from '../App'; 8 | 9 | // Note: test renderer must be required after react-native. 10 | import renderer from 'react-test-renderer'; 11 | 12 | it('renders correctly', () => { 13 | renderer.create(); 14 | }); 15 | -------------------------------------------------------------------------------- /template/android/app/BUCK: -------------------------------------------------------------------------------- 1 | # To learn about Buck see [Docs](https://buckbuild.com/). 2 | # To run your application with Buck: 3 | # - install Buck 4 | # - `npm start` - to start the packager 5 | # - `cd android` 6 | # - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"` 7 | # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck 8 | # - `buck install -r android/app` - compile, install and run application 9 | # 10 | 11 | load(":build_defs.bzl", "create_aar_targets", "create_jar_targets") 12 | 13 | lib_deps = [] 14 | 15 | create_aar_targets(glob(["libs/*.aar"])) 16 | 17 | create_jar_targets(glob(["libs/*.jar"])) 18 | 19 | android_library( 20 | name = "all-libs", 21 | exported_deps = lib_deps, 22 | ) 23 | 24 | android_library( 25 | name = "app-code", 26 | srcs = glob([ 27 | "src/main/java/**/*.java", 28 | ]), 29 | deps = [ 30 | ":all-libs", 31 | ":build_config", 32 | ":res", 33 | ], 34 | ) 35 | 36 | android_build_config( 37 | name = "build_config", 38 | package = "com.kaa", 39 | ) 40 | 41 | android_resource( 42 | name = "res", 43 | package = "com.kaa", 44 | res = "src/main/res", 45 | ) 46 | 47 | android_binary( 48 | name = "app", 49 | keystore = "//android/keystores:debug", 50 | manifest = "src/main/AndroidManifest.xml", 51 | package_type = "debug", 52 | deps = [ 53 | ":app-code", 54 | ], 55 | ) 56 | -------------------------------------------------------------------------------- /template/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.application" 2 | 3 | import com.android.build.OutputFile 4 | 5 | /** 6 | * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets 7 | * and bundleReleaseJsAndAssets). 8 | * These basically call `react-native bundle` with the correct arguments during the Android build 9 | * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the 10 | * bundle directly from the development server. Below you can see all the possible configurations 11 | * and their defaults. If you decide to add a configuration block, make sure to add it before the 12 | * `apply from: "../../node_modules/react-native/react.gradle"` line. 13 | * 14 | * project.ext.react = [ 15 | * // the name of the generated asset file containing your JS bundle 16 | * bundleAssetName: "index.android.bundle", 17 | * 18 | * // the entry file for bundle generation 19 | * entryFile: "index.android.js", 20 | * 21 | * // https://facebook.github.io/react-native/docs/performance#enable-the-ram-format 22 | * bundleCommand: "ram-bundle", 23 | * 24 | * // whether to bundle JS and assets in debug mode 25 | * bundleInDebug: false, 26 | * 27 | * // whether to bundle JS and assets in release mode 28 | * bundleInRelease: true, 29 | * 30 | * // whether to bundle JS and assets in another build variant (if configured). 31 | * // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants 32 | * // The configuration property can be in the following formats 33 | * // 'bundleIn${productFlavor}${buildType}' 34 | * // 'bundleIn${buildType}' 35 | * // bundleInFreeDebug: true, 36 | * // bundleInPaidRelease: true, 37 | * // bundleInBeta: true, 38 | * 39 | * // whether to disable dev mode in custom build variants (by default only disabled in release) 40 | * // for example: to disable dev mode in the staging build type (if configured) 41 | * devDisabledInStaging: true, 42 | * // The configuration property can be in the following formats 43 | * // 'devDisabledIn${productFlavor}${buildType}' 44 | * // 'devDisabledIn${buildType}' 45 | * 46 | * // the root of your project, i.e. where "package.json" lives 47 | * root: "../../", 48 | * 49 | * // where to put the JS bundle asset in debug mode 50 | * jsBundleDirDebug: "$buildDir/intermediates/assets/debug", 51 | * 52 | * // where to put the JS bundle asset in release mode 53 | * jsBundleDirRelease: "$buildDir/intermediates/assets/release", 54 | * 55 | * // where to put drawable resources / React Native assets, e.g. the ones you use via 56 | * // require('./image.png')), in debug mode 57 | * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug", 58 | * 59 | * // where to put drawable resources / React Native assets, e.g. the ones you use via 60 | * // require('./image.png')), in release mode 61 | * resourcesDirRelease: "$buildDir/intermediates/res/merged/release", 62 | * 63 | * // by default the gradle tasks are skipped if none of the JS files or assets change; this means 64 | * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to 65 | * // date; if you have any other folders that you want to ignore for performance reasons (gradle 66 | * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/ 67 | * // for example, you might want to remove it from here. 68 | * inputExcludes: ["android/**", "ios/**"], 69 | * 70 | * // override which node gets called and with what additional arguments 71 | * nodeExecutableAndArgs: ["node"], 72 | * 73 | * // supply additional arguments to the packager 74 | * extraPackagerArgs: [] 75 | * ] 76 | */ 77 | 78 | project.ext.react = [ 79 | entryFile: "index.js", 80 | enableHermes: false, // clean and rebuild if changing 81 | ] 82 | 83 | apply from: "../../node_modules/react-native/react.gradle" 84 | 85 | /** 86 | * Set this to true to create two separate APKs instead of one: 87 | * - An APK that only works on ARM devices 88 | * - An APK that only works on x86 devices 89 | * The advantage is the size of the APK is reduced by about 4MB. 90 | * Upload all the APKs to the Play Store and people will download 91 | * the correct one based on the CPU architecture of their device. 92 | */ 93 | def enableSeparateBuildPerCPUArchitecture = false 94 | 95 | /** 96 | * Run Proguard to shrink the Java bytecode in release builds. 97 | */ 98 | def enableProguardInReleaseBuilds = false 99 | 100 | /** 101 | * The preferred build flavor of JavaScriptCore. 102 | * 103 | * For example, to use the international variant, you can use: 104 | * `def jscFlavor = 'org.webkit:android-jsc-intl:+'` 105 | * 106 | * The international variant includes ICU i18n library and necessary data 107 | * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that 108 | * give correct results when using with locales other than en-US. Note that 109 | * this variant is about 6MiB larger per architecture than default. 110 | */ 111 | def jscFlavor = 'org.webkit:android-jsc:+' 112 | 113 | /** 114 | * Whether to enable the Hermes VM. 115 | * 116 | * This should be set on project.ext.react and mirrored here. If it is not set 117 | * on project.ext.react, JavaScript will not be compiled to Hermes Bytecode 118 | * and the benefits of using Hermes will therefore be sharply reduced. 119 | */ 120 | def enableHermes = project.ext.react.get("enableHermes", false); 121 | 122 | android { 123 | compileSdkVersion rootProject.ext.compileSdkVersion 124 | 125 | compileOptions { 126 | sourceCompatibility JavaVersion.VERSION_1_8 127 | targetCompatibility JavaVersion.VERSION_1_8 128 | } 129 | 130 | defaultConfig { 131 | applicationId "com.kaa" 132 | minSdkVersion rootProject.ext.minSdkVersion 133 | targetSdkVersion rootProject.ext.targetSdkVersion 134 | versionCode 1 135 | versionName "1.0" 136 | } 137 | splits { 138 | abi { 139 | reset() 140 | enable enableSeparateBuildPerCPUArchitecture 141 | universalApk false // If true, also generate a universal APK 142 | include "armeabi-v7a", "x86", "arm64-v8a", "x86_64" 143 | } 144 | } 145 | signingConfigs { 146 | debug { 147 | storeFile file('debug.keystore') 148 | storePassword 'android' 149 | keyAlias 'androiddebugkey' 150 | keyPassword 'android' 151 | } 152 | } 153 | buildTypes { 154 | debug { 155 | signingConfig signingConfigs.debug 156 | } 157 | release { 158 | // Caution! In production, you need to generate your own keystore file. 159 | // see https://facebook.github.io/react-native/docs/signed-apk-android. 160 | signingConfig signingConfigs.debug 161 | minifyEnabled enableProguardInReleaseBuilds 162 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 163 | } 164 | } 165 | // applicationVariants are e.g. debug, release 166 | applicationVariants.all { variant -> 167 | variant.outputs.each { output -> 168 | // For each separate APK per architecture, set a unique version code as described here: 169 | // https://developer.android.com/studio/build/configure-apk-splits.html 170 | def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4] 171 | def abi = output.getFilter(OutputFile.ABI) 172 | if (abi != null) { // null for the universal-debug, universal-release variants 173 | output.versionCodeOverride = 174 | versionCodes.get(abi) * 1048576 + defaultConfig.versionCode 175 | } 176 | 177 | } 178 | } 179 | 180 | packagingOptions { 181 | pickFirst '**/armeabi-v7a/libc++_shared.so' 182 | pickFirst '**/x86/libc++_shared.so' 183 | pickFirst '**/arm64-v8a/libc++_shared.so' 184 | pickFirst '**/x86_64/libc++_shared.so' 185 | pickFirst '**/x86/libjsc.so' 186 | pickFirst '**/armeabi-v7a/libjsc.so' 187 | } 188 | } 189 | 190 | dependencies { 191 | implementation fileTree(dir: "libs", include: ["*.jar"]) 192 | implementation "com.facebook.react:react-native:+" // From node_modules 193 | 194 | if (enableHermes) { 195 | def hermesPath = "../../node_modules/hermesvm/android/"; 196 | debugImplementation files(hermesPath + "hermes-debug.aar") 197 | releaseImplementation files(hermesPath + "hermes-release.aar") 198 | } else { 199 | implementation jscFlavor 200 | } 201 | } 202 | 203 | // Run this once to be able to run the application with BUCK 204 | // puts all compile dependencies into folder libs for BUCK to use 205 | task copyDownloadableDepsToLibs(type: Copy) { 206 | from configurations.compile 207 | into 'libs' 208 | } 209 | 210 | apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) 211 | -------------------------------------------------------------------------------- /template/android/app/build_defs.bzl: -------------------------------------------------------------------------------- 1 | """Helper definitions to glob .aar and .jar targets""" 2 | 3 | def create_aar_targets(aarfiles): 4 | for aarfile in aarfiles: 5 | name = "aars__" + aarfile[aarfile.rindex("/") + 1:aarfile.rindex(".aar")] 6 | lib_deps.append(":" + name) 7 | android_prebuilt_aar( 8 | name = name, 9 | aar = aarfile, 10 | ) 11 | 12 | def create_jar_targets(jarfiles): 13 | for jarfile in jarfiles: 14 | name = "jars__" + jarfile[jarfile.rindex("/") + 1:jarfile.rindex(".jar")] 15 | lib_deps.append(":" + name) 16 | prebuilt_jar( 17 | name = name, 18 | binary_jar = jarfile, 19 | ) 20 | -------------------------------------------------------------------------------- /template/android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | -------------------------------------------------------------------------------- /template/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /template/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 13 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /template/android/app/src/main/java/com/glider/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.glider; 2 | 3 | import com.facebook.react.ReactActivity; 4 | 5 | public class MainActivity extends ReactActivity { 6 | 7 | /** 8 | * Returns the name of the main component registered from JavaScript. 9 | * This is used to schedule rendering of the component. 10 | */ 11 | @Override 12 | protected String getMainComponentName() { 13 | return "Glider"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /template/android/app/src/main/java/com/glider/MainApplication.java: -------------------------------------------------------------------------------- 1 | package com.glider; 2 | 3 | import android.app.Application; 4 | import android.util.Log; 5 | 6 | import com.facebook.react.PackageList; 7 | import com.facebook.hermes.reactexecutor.HermesExecutorFactory; 8 | import com.facebook.react.bridge.JavaScriptExecutorFactory; 9 | import com.facebook.react.ReactApplication; 10 | import com.facebook.react.ReactNativeHost; 11 | import com.facebook.react.ReactPackage; 12 | import com.facebook.soloader.SoLoader; 13 | 14 | import java.util.List; 15 | 16 | public class MainApplication extends Application implements ReactApplication { 17 | 18 | private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { 19 | @Override 20 | public boolean getUseDeveloperSupport() { 21 | return BuildConfig.DEBUG; 22 | } 23 | 24 | @Override 25 | protected List getPackages() { 26 | @SuppressWarnings("UnnecessaryLocalVariable") 27 | List packages = new PackageList(this).getPackages(); 28 | // Packages that cannot be autolinked yet can be added manually here, for example: 29 | // packages.add(new MyReactNativePackage()); 30 | return packages; 31 | } 32 | 33 | @Override 34 | protected String getJSMainModuleName() { 35 | return "index"; 36 | } 37 | }; 38 | 39 | @Override 40 | public ReactNativeHost getReactNativeHost() { 41 | return mReactNativeHost; 42 | } 43 | 44 | @Override 45 | public void onCreate() { 46 | super.onCreate(); 47 | SoLoader.init(this, /* native exopackage */ false); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /template/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/glider/e463b130cb19464031fe94904c554743cd353442/template/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /template/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/glider/e463b130cb19464031fe94904c554743cd353442/template/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /template/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/glider/e463b130cb19464031fe94904c554743cd353442/template/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /template/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/glider/e463b130cb19464031fe94904c554743cd353442/template/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /template/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/glider/e463b130cb19464031fe94904c554743cd353442/template/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /template/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/glider/e463b130cb19464031fe94904c554743cd353442/template/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /template/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/glider/e463b130cb19464031fe94904c554743cd353442/template/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /template/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/glider/e463b130cb19464031fe94904c554743cd353442/template/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /template/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/glider/e463b130cb19464031fe94904c554743cd353442/template/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /template/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/glider/e463b130cb19464031fe94904c554743cd353442/template/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /template/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Glider 3 | 4 | -------------------------------------------------------------------------------- /template/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /template/android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | ext { 5 | buildToolsVersion = "28.0.3" 6 | minSdkVersion = 16 7 | compileSdkVersion = 28 8 | targetSdkVersion = 28 9 | supportLibVersion = "28.0.0" 10 | } 11 | repositories { 12 | google() 13 | jcenter() 14 | } 15 | dependencies { 16 | classpath("com.android.tools.build:gradle:3.4.1") 17 | 18 | // NOTE: Do not place your application dependencies here; they belong 19 | // in the individual module build.gradle files 20 | } 21 | } 22 | 23 | allprojects { 24 | repositories { 25 | mavenLocal() 26 | maven { 27 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 28 | url("$rootDir/../node_modules/react-native/android") 29 | } 30 | maven { 31 | // Android JSC is installed from npm 32 | url("$rootDir/../node_modules/jsc-android/dist") 33 | } 34 | 35 | google() 36 | jcenter() 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /template/android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | android.useAndroidX=true 21 | android.enableJetifier=true 22 | -------------------------------------------------------------------------------- /template/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/glider/e463b130cb19464031fe94904c554743cd353442/template/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /template/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /template/android/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | # Determine the Java command to use to start the JVM. 86 | if [ -n "$JAVA_HOME" ] ; then 87 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 88 | # IBM's JDK on AIX uses strange locations for the executables 89 | JAVACMD="$JAVA_HOME/jre/sh/java" 90 | else 91 | JAVACMD="$JAVA_HOME/bin/java" 92 | fi 93 | if [ ! -x "$JAVACMD" ] ; then 94 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 95 | 96 | Please set the JAVA_HOME variable in your environment to match the 97 | location of your Java installation." 98 | fi 99 | else 100 | JAVACMD="java" 101 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 102 | 103 | Please set the JAVA_HOME variable in your environment to match the 104 | location of your Java installation." 105 | fi 106 | 107 | # Increase the maximum file descriptors if we can. 108 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 109 | MAX_FD_LIMIT=`ulimit -H -n` 110 | if [ $? -eq 0 ] ; then 111 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 112 | MAX_FD="$MAX_FD_LIMIT" 113 | fi 114 | ulimit -n $MAX_FD 115 | if [ $? -ne 0 ] ; then 116 | warn "Could not set maximum file descriptor limit: $MAX_FD" 117 | fi 118 | else 119 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 120 | fi 121 | fi 122 | 123 | # For Darwin, add options to specify how the application appears in the dock 124 | if $darwin; then 125 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 126 | fi 127 | 128 | # For Cygwin, switch paths to Windows format before running java 129 | if $cygwin ; then 130 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 131 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 132 | JAVACMD=`cygpath --unix "$JAVACMD"` 133 | 134 | # We build the pattern for arguments to be converted via cygpath 135 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 136 | SEP="" 137 | for dir in $ROOTDIRSRAW ; do 138 | ROOTDIRS="$ROOTDIRS$SEP$dir" 139 | SEP="|" 140 | done 141 | OURCYGPATTERN="(^($ROOTDIRS))" 142 | # Add a user-defined pattern to the cygpath arguments 143 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 144 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 145 | fi 146 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 147 | i=0 148 | for arg in "$@" ; do 149 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 150 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 151 | 152 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 153 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 154 | else 155 | eval `echo args$i`="\"$arg\"" 156 | fi 157 | i=$((i+1)) 158 | done 159 | case $i in 160 | (0) set -- ;; 161 | (1) set -- "$args0" ;; 162 | (2) set -- "$args0" "$args1" ;; 163 | (3) set -- "$args0" "$args1" "$args2" ;; 164 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 165 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 166 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 167 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 168 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 169 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 170 | esac 171 | fi 172 | 173 | # Escape application args 174 | save () { 175 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 176 | echo " " 177 | } 178 | APP_ARGS=$(save "$@") 179 | 180 | # Collect all arguments for the java command, following the shell quoting and substitution rules 181 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 182 | 183 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 184 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 185 | cd "$(dirname "$0")" 186 | fi 187 | 188 | exec "$JAVACMD" "$@" 189 | -------------------------------------------------------------------------------- /template/android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem http://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 33 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 34 | 35 | @rem Find java.exe 36 | if defined JAVA_HOME goto findJavaFromJavaHome 37 | 38 | set JAVA_EXE=java.exe 39 | %JAVA_EXE% -version >NUL 2>&1 40 | if "%ERRORLEVEL%" == "0" goto init 41 | 42 | echo. 43 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 44 | echo. 45 | echo Please set the JAVA_HOME variable in your environment to match the 46 | echo location of your Java installation. 47 | 48 | goto fail 49 | 50 | :findJavaFromJavaHome 51 | set JAVA_HOME=%JAVA_HOME:"=% 52 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 53 | 54 | if exist "%JAVA_EXE%" goto init 55 | 56 | echo. 57 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 58 | echo. 59 | echo Please set the JAVA_HOME variable in your environment to match the 60 | echo location of your Java installation. 61 | 62 | goto fail 63 | 64 | :init 65 | @rem Get command-line arguments, handling Windows variants 66 | 67 | if not "%OS%" == "Windows_NT" goto win9xME_args 68 | 69 | :win9xME_args 70 | @rem Slurp the command line arguments. 71 | set CMD_LINE_ARGS= 72 | set _SKIP=2 73 | 74 | :win9xME_args_slurp 75 | if "x%~1" == "x" goto execute 76 | 77 | set CMD_LINE_ARGS=%* 78 | 79 | :execute 80 | @rem Setup the command line 81 | 82 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 83 | 84 | @rem Execute Gradle 85 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 86 | 87 | :end 88 | @rem End local scope for the variables with windows NT shell 89 | if "%ERRORLEVEL%"=="0" goto mainEnd 90 | 91 | :fail 92 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 93 | rem the _cmd.exe /c_ return code! 94 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 95 | exit /b 1 96 | 97 | :mainEnd 98 | if "%OS%"=="Windows_NT" endlocal 99 | 100 | :omega 101 | -------------------------------------------------------------------------------- /template/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'Glider' 2 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) 3 | include ':app' 4 | -------------------------------------------------------------------------------- /template/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Glider", 3 | "displayName": "Glider" 4 | } -------------------------------------------------------------------------------- /template/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:metro-react-native-babel-preset'], 3 | }; 4 | -------------------------------------------------------------------------------- /template/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import {AppRegistry} from 'react-native'; 6 | import App from './App'; 7 | import {name as appName} from './app.json'; 8 | 9 | AppRegistry.registerComponent(appName, () => App); 10 | -------------------------------------------------------------------------------- /template/ios/Glider-tvOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | NSAppTransportSecurity 26 | 27 | NSExceptionDomains 28 | 29 | localhost 30 | 31 | NSExceptionAllowsInsecureHTTPLoads 32 | 33 | 34 | 35 | 36 | NSLocationWhenInUseUsageDescription 37 | 38 | UILaunchStoryboardName 39 | LaunchScreen 40 | UIRequiredDeviceCapabilities 41 | 42 | armv7 43 | 44 | UISupportedInterfaceOrientations 45 | 46 | UIInterfaceOrientationPortrait 47 | UIInterfaceOrientationLandscapeLeft 48 | UIInterfaceOrientationLandscapeRight 49 | 50 | UIViewControllerBasedStatusBarAppearance 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /template/ios/Glider-tvOSTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /template/ios/Glider.xcodeproj/xcshareddata/xcschemes/Glider-tvOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 43 | 49 | 50 | 51 | 52 | 53 | 58 | 59 | 61 | 67 | 68 | 69 | 70 | 71 | 77 | 78 | 79 | 80 | 81 | 82 | 92 | 94 | 100 | 101 | 102 | 103 | 104 | 105 | 111 | 113 | 119 | 120 | 121 | 122 | 124 | 125 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /template/ios/Glider.xcodeproj/xcshareddata/xcschemes/Glider.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 43 | 49 | 50 | 51 | 52 | 53 | 58 | 59 | 61 | 67 | 68 | 69 | 70 | 71 | 77 | 78 | 79 | 80 | 81 | 82 | 92 | 94 | 100 | 101 | 102 | 103 | 104 | 105 | 111 | 113 | 119 | 120 | 121 | 122 | 124 | 125 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /template/ios/Glider/AppDelegate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (nonatomic, strong) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /template/ios/Glider/AppDelegate.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "AppDelegate.h" 9 | 10 | #import 11 | #import 12 | #import 13 | 14 | @implementation AppDelegate 15 | 16 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 17 | { 18 | RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions]; 19 | RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge 20 | moduleName:@"Glider" 21 | initialProperties:nil]; 22 | 23 | rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; 24 | 25 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 26 | UIViewController *rootViewController = [UIViewController new]; 27 | rootViewController.view = rootView; 28 | self.window.rootViewController = rootViewController; 29 | [self.window makeKeyAndVisible]; 30 | return YES; 31 | } 32 | 33 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge 34 | { 35 | #if DEBUG 36 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; 37 | #else 38 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 39 | #endif 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /template/ios/Glider/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 21 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /template/ios/Glider/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /template/ios/Glider/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /template/ios/Glider/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | Glider 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSRequiresIPhoneOS 26 | 27 | NSAppTransportSecurity 28 | 29 | NSAllowsArbitraryLoads 30 | 31 | NSExceptionDomains 32 | 33 | localhost 34 | 35 | NSExceptionAllowsInsecureHTTPLoads 36 | 37 | 38 | 39 | 40 | NSLocationWhenInUseUsageDescription 41 | 42 | UILaunchStoryboardName 43 | LaunchScreen 44 | UIRequiredDeviceCapabilities 45 | 46 | armv7 47 | 48 | UISupportedInterfaceOrientations 49 | 50 | UIInterfaceOrientationPortrait 51 | UIInterfaceOrientationLandscapeLeft 52 | UIInterfaceOrientationLandscapeRight 53 | 54 | UIViewControllerBasedStatusBarAppearance 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /template/ios/Glider/main.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import 9 | 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /template/ios/GliderTests/GliderTests.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import 9 | #import 10 | 11 | #import 12 | #import 13 | 14 | #define TIMEOUT_SECONDS 600 15 | #define TEXT_TO_LOOK_FOR @"Welcome to React Native!" 16 | 17 | @interface GliderTests : XCTestCase 18 | 19 | @end 20 | 21 | @implementation GliderTests 22 | 23 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test 24 | { 25 | if (test(view)) { 26 | return YES; 27 | } 28 | for (UIView *subview in [view subviews]) { 29 | if ([self findSubviewInView:subview matching:test]) { 30 | return YES; 31 | } 32 | } 33 | return NO; 34 | } 35 | 36 | - (void)testRendersWelcomeScreen 37 | { 38 | UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController]; 39 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; 40 | BOOL foundElement = NO; 41 | 42 | __block NSString *redboxError = nil; 43 | RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { 44 | if (level >= RCTLogLevelError) { 45 | redboxError = message; 46 | } 47 | }); 48 | 49 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { 50 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 51 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 52 | 53 | foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) { 54 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { 55 | return YES; 56 | } 57 | return NO; 58 | }]; 59 | } 60 | 61 | RCTSetLogFunction(RCTDefaultLogFunction); 62 | 63 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); 64 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); 65 | } 66 | 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /template/ios/GliderTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /template/ios/Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '9.0' 2 | require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' 3 | 4 | target 'Glider' do 5 | # Pods for Glider 6 | pod 'React', :path => '../node_modules/react-native/' 7 | pod 'React-Core', :path => '../node_modules/react-native/React' 8 | pod 'React-DevSupport', :path => '../node_modules/react-native/React' 9 | pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS' 10 | pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation' 11 | pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob' 12 | pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image' 13 | pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS' 14 | pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network' 15 | pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings' 16 | pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text' 17 | pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration' 18 | pod 'React-RCTWebSocket', :path => '../node_modules/react-native/Libraries/WebSocket' 19 | 20 | pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact' 21 | pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi' 22 | pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor' 23 | pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector' 24 | pod 'yoga', :path => '../node_modules/react-native/ReactCommon/yoga' 25 | 26 | pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec' 27 | pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec' 28 | pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec' 29 | 30 | target 'GliderTests' do 31 | inherit! :search_paths 32 | # Pods for testing 33 | end 34 | 35 | use_native_modules! 36 | end 37 | 38 | target 'Glider-tvOS' do 39 | # Pods for Glider-tvOS 40 | 41 | target 'Glider-tvOSTests' do 42 | inherit! :search_paths 43 | # Pods for testing 44 | end 45 | 46 | end 47 | -------------------------------------------------------------------------------- /template/metro.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Metro configuration for React Native 3 | * https://github.com/facebook/react-native 4 | * 5 | * @format 6 | */ 7 | 8 | module.exports = { 9 | transformer: { 10 | getTransformOptions: async () => ({ 11 | transform: { 12 | experimentalImportSupport: false, 13 | inlineRequires: false, 14 | }, 15 | }), 16 | }, 17 | }; 18 | --------------------------------------------------------------------------------