├── .github └── workflows │ ├── build.yml │ ├── deploy.yml │ └── test.yml ├── .gitignore ├── .husky └── pre-commit ├── LICENSE ├── README.md ├── lerna.json ├── package.json ├── packages ├── 008 │ ├── .eslintignore │ ├── .eslintrc.js │ ├── .gitignore │ ├── .prettierignore │ ├── .prettierrc │ ├── .storybook-web │ │ ├── main.js │ │ └── preview.js │ ├── .storybook │ │ ├── index.js │ │ ├── main.js │ │ ├── preview.js │ │ └── storybook.requires.js │ ├── App.js │ ├── android │ │ ├── .gitignore │ │ ├── app │ │ │ ├── build.gradle │ │ │ ├── debug.keystore │ │ │ ├── proguard-rules.pro │ │ │ └── src │ │ │ │ ├── debug │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java │ │ │ │ │ └── com │ │ │ │ │ └── anonymous │ │ │ │ │ └── softphone │ │ │ │ │ └── ReactNativeFlipper.java │ │ │ │ ├── main │ │ │ │ ├── AndroidManifest.xml │ │ │ │ ├── java │ │ │ │ │ └── com │ │ │ │ │ │ └── anonymous │ │ │ │ │ │ └── softphone │ │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ │ └── MainApplication.java │ │ │ │ └── res │ │ │ │ │ ├── drawable-hdpi │ │ │ │ │ └── splashscreen_image.png │ │ │ │ │ ├── drawable-mdpi │ │ │ │ │ └── splashscreen_image.png │ │ │ │ │ ├── drawable-xhdpi │ │ │ │ │ └── splashscreen_image.png │ │ │ │ │ ├── drawable-xxhdpi │ │ │ │ │ └── splashscreen_image.png │ │ │ │ │ ├── drawable-xxxhdpi │ │ │ │ │ └── splashscreen_image.png │ │ │ │ │ ├── drawable │ │ │ │ │ ├── rn_edit_text_material.xml │ │ │ │ │ └── splashscreen.xml │ │ │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ │ ├── ic_launcher.xml │ │ │ │ │ └── ic_launcher_round.xml │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ ├── ic_launcher_foreground.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ ├── ic_launcher_foreground.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ ├── ic_launcher_foreground.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ ├── ic_launcher_foreground.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ ├── ic_launcher_foreground.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── values-night │ │ │ │ │ └── colors.xml │ │ │ │ │ └── values │ │ │ │ │ ├── colors.xml │ │ │ │ │ ├── strings.xml │ │ │ │ │ └── styles.xml │ │ │ │ └── release │ │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── anonymous │ │ │ │ └── softphone │ │ │ │ └── ReactNativeFlipper.java │ │ ├── build.gradle │ │ ├── gradle.properties │ │ ├── gradle │ │ │ └── wrapper │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ └── settings.gradle │ ├── app.json │ ├── assets │ │ ├── adaptive-icon.png │ │ ├── fonts │ │ │ └── Roboto-Flex.ttf │ │ ├── icon.png │ │ └── splash.png │ ├── babel.config.js │ ├── cypress.config.js │ ├── cypress │ │ ├── e2e │ │ │ └── spec.cy.js │ │ ├── fixtures │ │ │ └── example.json │ │ └── support │ │ │ ├── commands.js │ │ │ └── e2e.js │ ├── index.js │ ├── ios │ │ ├── .gitignore │ │ ├── .xcode.env │ │ ├── Podfile │ │ ├── Podfile.properties.json │ │ ├── softphone.xcodeproj │ │ │ ├── project.pbxproj │ │ │ └── xcshareddata │ │ │ │ └── xcschemes │ │ │ │ └── softphone.xcscheme │ │ └── softphone │ │ │ ├── AppDelegate.h │ │ │ ├── AppDelegate.mm │ │ │ ├── Images.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ ├── App-Icon-20x20@1x.png │ │ │ │ ├── App-Icon-20x20@2x.png │ │ │ │ ├── App-Icon-20x20@3x.png │ │ │ │ ├── App-Icon-29x29@1x.png │ │ │ │ ├── App-Icon-29x29@2x.png │ │ │ │ ├── App-Icon-29x29@3x.png │ │ │ │ ├── App-Icon-40x40@1x.png │ │ │ │ ├── App-Icon-40x40@2x.png │ │ │ │ ├── App-Icon-40x40@3x.png │ │ │ │ ├── App-Icon-60x60@2x.png │ │ │ │ ├── App-Icon-60x60@3x.png │ │ │ │ ├── App-Icon-76x76@1x.png │ │ │ │ ├── App-Icon-76x76@2x.png │ │ │ │ ├── App-Icon-83.5x83.5@2x.png │ │ │ │ ├── Contents.json │ │ │ │ └── ItunesArtwork@2x.png │ │ │ ├── Contents.json │ │ │ ├── SplashScreen.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── image.png │ │ │ └── SplashScreenBackground.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── image.png │ │ │ ├── Info.plist │ │ │ ├── SplashScreen.storyboard │ │ │ ├── Supporting │ │ │ └── Expo.plist │ │ │ ├── main.m │ │ │ ├── noop-file.swift │ │ │ └── softphone.entitlements │ ├── metro.config.js │ ├── package.json │ ├── src │ │ ├── 008QWorkerLLM.js │ │ ├── 008QWorkerTTS.js │ │ ├── Sip.js │ │ ├── Sound.js │ │ ├── components │ │ │ ├── Addons.jsx │ │ │ ├── Avatars.jsx │ │ │ ├── Basics.jsx │ │ │ ├── Container.jsx │ │ │ ├── Container.web.jsx │ │ │ ├── Dialer.jsx │ │ │ ├── Forms.jsx │ │ │ ├── Icons.jsx │ │ │ ├── Lists.jsx │ │ │ ├── Phone │ │ │ │ ├── Components.jsx │ │ │ │ └── index.js │ │ │ ├── Player.jsx │ │ │ └── Timer.jsx │ │ ├── screens │ │ │ ├── PhoneScreen.jsx │ │ │ ├── Screen.jsx │ │ │ ├── SessionScreen.jsx │ │ │ ├── SettingsScreen.jsx │ │ │ └── index.js │ │ ├── store │ │ │ ├── Cdr.js │ │ │ ├── Contacts.js │ │ │ ├── Context.js │ │ │ ├── Electron.js │ │ │ └── Events.js │ │ └── utils.js │ ├── stories │ │ ├── App.stories.js │ │ ├── CancelAccept.stories.js │ │ ├── DialGrid.stories.js │ │ ├── DialPad.stories.js │ │ ├── Dialer.stories.js │ │ ├── Screen.stories.js │ │ ├── SessionScreen.stories.js │ │ └── SettingsScreen.stories.js │ ├── web │ │ ├── assets │ │ │ ├── fonts │ │ │ │ └── Roboto-Flex.ttf │ │ │ ├── icons │ │ │ │ ├── 008.svg │ │ │ │ └── unanchor.svg │ │ │ └── sounds │ │ │ │ ├── busy.mp3 │ │ │ │ ├── dtmf │ │ │ │ ├── dtmf-0.mp3 │ │ │ │ ├── dtmf-1.mp3 │ │ │ │ ├── dtmf-2.mp3 │ │ │ │ ├── dtmf-3.mp3 │ │ │ │ ├── dtmf-4.mp3 │ │ │ │ ├── dtmf-5.mp3 │ │ │ │ ├── dtmf-6.mp3 │ │ │ │ ├── dtmf-7.mp3 │ │ │ │ ├── dtmf-8.mp3 │ │ │ │ ├── dtmf-9.mp3 │ │ │ │ ├── dtmf-hash.mp3 │ │ │ │ └── dtmf-star.mp3 │ │ │ │ ├── ring.mp3 │ │ │ │ └── ringback.mp3 │ │ ├── avatar.png │ │ ├── cfgDemo008.json │ │ ├── favicon.png │ │ ├── icon.png │ │ └── index.html │ ├── webpack.config.js │ └── yarn.lock ├── 008Q │ ├── .eslintignore │ ├── .eslintrc.js │ ├── index.js │ ├── package.json │ ├── playground │ │ ├── carrental.mp3 │ │ ├── carrental.ogg │ │ ├── carrental.wav │ │ ├── index.html │ │ ├── index.js │ │ └── static │ │ │ ├── ort-wasm-simd-threaded.jsep.wasm │ │ │ ├── ort-wasm-simd-threaded.wasm │ │ │ ├── ort-wasm-simd.jsep.wasm │ │ │ ├── ort-wasm-simd.wasm │ │ │ ├── ort-wasm-threaded.wasm │ │ │ └── ort-wasm.wasm │ ├── src │ │ └── Q.js │ └── webpack.config.js ├── 008desktop │ ├── .eslintignore │ ├── .eslintrc.js │ ├── .prettierignore │ ├── .prettierrc │ ├── assets │ │ ├── logo-round.png │ │ ├── logo.png │ │ ├── tray.ico │ │ ├── tray@2x.png │ │ ├── trayd@2x.png │ │ ├── trayl@2x.png │ │ └── trayp@2x.png │ ├── build │ │ └── entitlements.mac.plist │ ├── index.js │ ├── loader.js │ ├── package.json │ ├── scripts │ │ └── notarize.js │ ├── utils.js │ └── yarn.lock └── web-llm │ ├── cache_util.d.ts │ ├── cache_util.d.ts.map │ ├── chat_module.d.ts │ ├── chat_module.d.ts.map │ ├── config.d.ts │ ├── config.d.ts.map │ ├── conversation.d.ts │ ├── conversation.d.ts.map │ ├── engine.d.ts │ ├── engine.d.ts.map │ ├── grammar.d.ts │ ├── grammar.d.ts.map │ ├── index.d.ts │ ├── index.d.ts.map │ ├── index.js │ ├── index.js.map │ ├── llm_chat.d.ts │ ├── llm_chat.d.ts.map │ ├── message.d.ts │ ├── message.d.ts.map │ ├── openai_api_protocols │ ├── apis.d.ts │ ├── apis.d.ts.map │ ├── chat_completion.d.ts │ ├── chat_completion.d.ts.map │ ├── index.d.ts │ └── index.d.ts.map │ ├── service_worker.d.ts │ ├── service_worker.d.ts.map │ ├── support.d.ts │ ├── support.d.ts.map │ ├── types.d.ts │ ├── types.d.ts.map │ ├── web_worker.d.ts │ └── web_worker.d.ts.map └── yarn.lock /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | on: 4 | push: 5 | tags: 6 | - "v*" 7 | 8 | jobs: 9 | build: 10 | runs-on: [self-hosted, M1] 11 | permissions: 12 | contents: write 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | 17 | - uses: actions/setup-node@v2 18 | with: 19 | node-version: "18" 20 | 21 | - name: Build 22 | env: 23 | # CSC_LINK: ${{ secrets.MACOS_CERT }} 24 | # CSC_KEY_PASSWORD: ${{ secrets.MACOS_CERT_PASS }} 25 | NOT_APPLE_ID: ${{ secrets.APPLE_ID }} 26 | NOT_APPLE_ID_PASS: ${{ secrets.APPLE_ID_PASS }} 27 | run: | 28 | yarn install 29 | yarn run build-desktop 30 | 31 | - name: Upload artifacts 32 | uses: actions/upload-artifact@v2 33 | with: 34 | retention-days: 1 35 | path: | 36 | packages/008desktop/build/008-desktop-win.exe 37 | packages/008desktop/build/008-desktop-mac.dmg 38 | packages/008desktop/build/008-desktop-linux.AppImage 39 | 40 | sign-win: 41 | needs: build 42 | runs-on: windows-latest 43 | permissions: 44 | contents: write 45 | 46 | steps: 47 | - name: Download artifacts 48 | uses: actions/download-artifact@v2 49 | with: 50 | name: artifact 51 | path: bin 52 | 53 | - name: Sign win 54 | shell: bash 55 | run: | 56 | dotnet tool install --global AzureSignTool 57 | AzureSignTool sign -kvu "${{ secrets.AZURE_KEY_VAULT_URI }}" -kvi "${{ secrets.AZURE_CLIENT_ID }}" -kvt "${{ secrets.AZURE_TENANT_ID }}" -kvs "${{ secrets.AZURE_CLIENT_SECRET }}" -kvc ${{ secrets.AZURE_CERT_NAME }} -tr http://timestamp.digicert.com -v "bin/008-desktop-win.exe" 58 | 59 | - name: Release 60 | uses: softprops/action-gh-release@v1 61 | with: 62 | draft: true 63 | files: | 64 | bin/008-desktop* 65 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: deploy 2 | 3 | on: 4 | release: 5 | types: [released] 6 | workflow_dispatch: 7 | 8 | jobs: 9 | deploy: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - name: Upload agent008.ai 14 | timeout-minutes: 15 15 | shell: bash 16 | env: 17 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 18 | run: | 19 | gh release download --repo kunzite-app/008 --pattern '008-desktop*' --dir bin 20 | 21 | ls bin 22 | mkdir -p ~/.ssh 23 | ssh-keyscan -p ${{ secrets.SITE_PORT }} ${{ secrets.SITE_HOST }} >> ~/.ssh/known_hosts 24 | 25 | echo "${{ secrets.SITE_SSH_KEY }}" > private.key 26 | chmod 600 private.key 27 | 28 | scp -P ${{ secrets.SITE_PORT }} -i private.key -r bin ${{ secrets.SITE_USER }}@${{ secrets.SITE_HOST }}:~/public 29 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | on: pull_request 3 | 4 | jobs: 5 | test: 6 | env: 7 | SDL_VIDEODRIVER: "dummy" 8 | SDL_AUDIODRIVER: "disk" 9 | 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - uses: actions/checkout@v4 14 | 15 | - uses: actions/setup-node@v4 16 | with: 17 | node-version: 18 18 | 19 | - name: prerequisites 20 | run: | 21 | yarn install 22 | 23 | - name: lint 24 | run: | 25 | yarn lint 26 | 27 | - name: tests 28 | run: | 29 | yarn run e2e 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | tmp/ 4 | build/ 5 | lib/ 6 | dist/ 7 | node_modules/ 8 | storybook-static/ 9 | 10 | /.pnp/ 11 | **/.pnp.js 12 | 13 | # misc 14 | .DS_Store 15 | .env.local 16 | .env.development.local 17 | .env.test.local 18 | .env.production.local 19 | .eslintcache 20 | 21 | **/npm-debug.log* 22 | **/yarn-debug.log* 23 | **/yarn-error.log* 24 | **/lerna-debug.log* 25 | 26 | **/.vscode 27 | 28 | packages/008desktop/app 29 | packages/008desktop/binaries 30 | packages/008desktop/build/* 31 | !packages/008desktop/build/ 32 | !packages/008desktop/build/entitlements.mac.plist 33 | packages/008Q/**/models 34 | !packages/web-llm/lib 35 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | npx lint-staged 5 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "node_modules/lerna/schemas/lerna-schema.json", 3 | "npmClient": "yarn", 4 | "useWorkspaces": true, 5 | "version": "independent" 6 | } 7 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kunzite", 3 | "private": true, 4 | "workspaces": [ 5 | "packages/*" 6 | ], 7 | "devDependencies": { 8 | "husky": "^8.0.0", 9 | "lerna": "^6.1.0", 10 | "lint-staged": "^13.1.0" 11 | }, 12 | "scripts": { 13 | "start": "yarn start-desktop", 14 | "start-desktop": "lerna run web --scope @kunzite/008 & lerna run start --scope 008desktop", 15 | "build-web": "lerna run build-web", 16 | "build-desktop": "IS_ELECTRON=yes lerna run build-web && rm -rf packages/008desktop/app && mv packages/008/web-build packages/008desktop/app && cp -R packages/008desktop/app/static/ packages/008desktop/app/static2/ && mv packages/008desktop/app/static2 packages/008desktop/app/static/js/static && lerna run build --scope 008desktop", 17 | "clean": "lerna clean", 18 | "prepare": "husky install", 19 | "lint": "lerna run lint", 20 | "e2e": "lerna run e2e --scope @kunzite/008" 21 | }, 22 | "lint-staged": { 23 | "**/*.{js}": [ 24 | "lerna run lint -- --fix --quiet", 25 | "lerna run format -- --write ." 26 | ], 27 | "**/*.{json,md,yaml,yml}": [ 28 | "lerna run format -- --write ." 29 | ] 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/008/.eslintignore: -------------------------------------------------------------------------------- 1 | lib 2 | node_modules 3 | build 4 | web-build 5 | metro.config.js 6 | -------------------------------------------------------------------------------- /packages/008/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['universe/native', 'universe/web', 'plugin:cypress/recommended'], 3 | env: { 4 | browser: true, 5 | node: true 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /packages/008/.gitignore: -------------------------------------------------------------------------------- 1 | # Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files 2 | 3 | # dependencies 4 | node_modules/ 5 | 6 | # Expo 7 | .expo/ 8 | dist/ 9 | web-build/ 10 | 11 | # Native 12 | *.orig.* 13 | *.jks 14 | *.p8 15 | *.p12 16 | *.key 17 | *.mobileprovision 18 | 19 | # Metro 20 | .metro-health-check* 21 | 22 | # debug 23 | npm-debug.* 24 | yarn-debug.* 25 | yarn-error.* 26 | 27 | # macOS 28 | .DS_Store 29 | *.pem 30 | 31 | # local env files 32 | .env*.local 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | 37 | # @generated: @expo/electron-adapter@0.0.55 38 | /.expo/* 39 | # Expo Web 40 | /web-build/* 41 | # electron-webpack 42 | /dist 43 | # @end @expo/electron-adapter 44 | 45 | /web/config*.json 46 | /web/*.webm 47 | /web/*.wav 48 | /web/*.ogg 49 | /web/*.mp3 50 | /web/*.bin 51 | -------------------------------------------------------------------------------- /packages/008/.prettierignore: -------------------------------------------------------------------------------- 1 | lib 2 | node_modules 3 | build 4 | -------------------------------------------------------------------------------- /packages/008/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "arrowParens": "avoid", 6 | "singleQuote": true, 7 | "trailingComma": "none", 8 | "proseWrap": "always", 9 | "jsxSingleQuote": false 10 | } 11 | -------------------------------------------------------------------------------- /packages/008/.storybook-web/main.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | stories: ['../stories/**/*.stories.?(ts|tsx|js|jsx)'], 3 | addons: ['@storybook/addon-essentials', '@storybook/addon-react-native-web'], 4 | core: { 5 | builder: 'webpack5' 6 | }, 7 | framework: '@storybook/react', 8 | staticDirs: ['../web'] 9 | }; 10 | -------------------------------------------------------------------------------- /packages/008/.storybook-web/preview.js: -------------------------------------------------------------------------------- 1 | import { View } from 'react-native'; 2 | 3 | export const parameters = { 4 | controls: { 5 | matchers: { 6 | color: /(background|color)$/i, 7 | date: /Date$/ 8 | } 9 | } 10 | }; 11 | 12 | export const decorators = [ 13 | Story => ( 14 | 15 | 16 | 17 | ) 18 | ]; 19 | -------------------------------------------------------------------------------- /packages/008/.storybook/index.js: -------------------------------------------------------------------------------- 1 | import { getStorybookUI } from '@storybook/react-native'; 2 | 3 | import './storybook.requires'; 4 | 5 | const StorybookUIRoot = getStorybookUI({}); 6 | 7 | export default StorybookUIRoot; 8 | -------------------------------------------------------------------------------- /packages/008/.storybook/main.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | stories: ['../stories/**/*.stories.?(ts|tsx|js|jsx)'], 3 | addons: [ 4 | '@storybook/addon-ondevice-controls', 5 | '@storybook/addon-ondevice-actions' 6 | ] 7 | }; 8 | -------------------------------------------------------------------------------- /packages/008/.storybook/preview.js: -------------------------------------------------------------------------------- 1 | import { View } from 'react-native'; 2 | 3 | export const parameters = { 4 | controls: { 5 | matchers: { 6 | color: /(background|color)$/i, 7 | date: /Date$/ 8 | } 9 | } 10 | }; 11 | 12 | export const decorators = [ 13 | Story => ( 14 | 15 | 16 | 17 | ) 18 | ]; 19 | -------------------------------------------------------------------------------- /packages/008/.storybook/storybook.requires.js: -------------------------------------------------------------------------------- 1 | /* do not change this file, it is auto generated by storybook. */ 2 | 3 | import { 4 | configure, 5 | addDecorator, 6 | addParameters, 7 | addArgsEnhancer, 8 | clearDecorators 9 | } from '@storybook/react-native'; 10 | 11 | global.STORIES = [ 12 | { 13 | titlePrefix: '', 14 | directory: './stories', 15 | files: '**/*.stories.?(ts|tsx|js|jsx)', 16 | importPathMatcher: 17 | '^\\.[\\\\/](?:stories(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.(?:ts|tsx|js|jsx)?)$' 18 | } 19 | ]; 20 | 21 | import '@storybook/addon-ondevice-controls/register'; 22 | import '@storybook/addon-ondevice-actions/register'; 23 | 24 | import { argsEnhancers } from '@storybook/addon-actions/dist/modern/preset/addArgs'; 25 | 26 | import { decorators, parameters } from './preview'; 27 | 28 | if (decorators) { 29 | if (__DEV__) { 30 | // stops the warning from showing on every HMR 31 | require('react-native').LogBox.ignoreLogs([ 32 | '`clearDecorators` is deprecated and will be removed in Storybook 7.0' 33 | ]); 34 | } 35 | // workaround for global decorators getting infinitely applied on HMR, see https://github.com/storybookjs/react-native/issues/185 36 | clearDecorators(); 37 | decorators.forEach(decorator => addDecorator(decorator)); 38 | } 39 | 40 | if (parameters) { 41 | addParameters(parameters); 42 | } 43 | 44 | try { 45 | argsEnhancers.forEach(enhancer => addArgsEnhancer(enhancer)); 46 | } catch {} 47 | 48 | const getStories = () => { 49 | return { 50 | './stories/App.stories.js': require('../stories/App.stories.js'), 51 | './stories/LoginScreen.stories.js': require('../stories/LoginScreen.stories.js'), 52 | './stories/PhoneScreen.stories.js': require('../stories/PhoneScreen.stories.js'), 53 | './stories/Screen.stories.js': require('../stories/Screen.stories.js'), 54 | './stories/SettingsScreen.stories.js': require('../stories/SettingsScreen.stories.js') 55 | }; 56 | }; 57 | 58 | configure(getStories, module, false); 59 | -------------------------------------------------------------------------------- /packages/008/App.js: -------------------------------------------------------------------------------- 1 | import _ from 'lodash'; 2 | import { useEffect } from 'react'; 3 | import { View } from 'react-native'; 4 | 5 | import { ApplicationInsights } from '@microsoft/applicationinsights-web'; 6 | import { 7 | AppInsightsErrorBoundary, 8 | ReactPlugin 9 | } from '@microsoft/applicationinsights-react-js'; 10 | 11 | import { Button, COLORS, Text } from './src/components/Basics'; 12 | import { Container } from './src/components/Container'; 13 | import { SettingsScreen, PhoneScreen } from './src/screens'; 14 | import { ContextProvider, useStore } from './src/store/Context'; 15 | 16 | const reactPlugin = new ReactPlugin(); 17 | const appInsights = new ApplicationInsights({ 18 | config: { 19 | connectionString: 20 | 'InstrumentationKey=89ba4ad2-47ef-41e8-a151-4b3488132c63;IngestionEndpoint=https://westeurope-5.in.applicationinsights.azure.com/;LiveEndpoint=https://westeurope.livediagnostics.monitor.azure.com/', 21 | extensions: [reactPlugin] 22 | } 23 | }); 24 | appInsights.loadAppInsights(); 25 | appInsights.trackPageView(); 26 | 27 | export default function App() { 28 | const store = useStore(); 29 | const { settingsUri, toggleShowSettings, server, showSettings } = store; 30 | 31 | useEffect(() => { 32 | const mustSettings = !settingsUri; 33 | if (mustSettings) toggleShowSettings(true, 'connection'); 34 | else toggleShowSettings(false); 35 | }, [settingsUri]); 36 | 37 | return ( 38 | ( 40 | 43 | 52 | 53 | )} 54 | appInsights={reactPlugin} 55 | > 56 | 57 | 58 | {!server && } 59 | 63 | 64 | 65 | 66 | ); 67 | } 68 | -------------------------------------------------------------------------------- /packages/008/android/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Android/IntelliJ 6 | # 7 | build/ 8 | .idea 9 | .gradle 10 | local.properties 11 | *.iml 12 | *.hprof 13 | 14 | # Bundle artifacts 15 | *.jsbundle 16 | -------------------------------------------------------------------------------- /packages/008/android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/debug.keystore -------------------------------------------------------------------------------- /packages/008/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 | # react-native-reanimated 11 | -keep class com.swmansion.reanimated.** { *; } 12 | -keep class com.facebook.react.turbomodule.** { *; } 13 | 14 | # Add any project specific keep options here: 15 | -------------------------------------------------------------------------------- /packages/008/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /packages/008/android/app/src/debug/java/com/anonymous/softphone/ReactNativeFlipper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | *

This source code is licensed under the MIT license found in the LICENSE file in the root 5 | * directory of this source tree. 6 | */ 7 | package com.anonymous.softphone; 8 | 9 | import android.content.Context; 10 | import com.facebook.flipper.android.AndroidFlipperClient; 11 | import com.facebook.flipper.android.utils.FlipperUtils; 12 | import com.facebook.flipper.core.FlipperClient; 13 | import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin; 14 | import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin; 15 | import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin; 16 | import com.facebook.flipper.plugins.inspector.DescriptorMapping; 17 | import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin; 18 | import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor; 19 | import com.facebook.flipper.plugins.network.NetworkFlipperPlugin; 20 | import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin; 21 | import com.facebook.react.ReactInstanceEventListener; 22 | import com.facebook.react.ReactInstanceManager; 23 | import com.facebook.react.bridge.ReactContext; 24 | import com.facebook.react.modules.network.NetworkingModule; 25 | import okhttp3.OkHttpClient; 26 | 27 | /** 28 | * Class responsible of loading Flipper inside your React Native application. This is the debug 29 | * flavor of it. Here you can add your own plugins and customize the Flipper setup. 30 | */ 31 | public class ReactNativeFlipper { 32 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { 33 | if (FlipperUtils.shouldEnableFlipper(context)) { 34 | final FlipperClient client = AndroidFlipperClient.getInstance(context); 35 | 36 | client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults())); 37 | client.addPlugin(new DatabasesFlipperPlugin(context)); 38 | client.addPlugin(new SharedPreferencesFlipperPlugin(context)); 39 | client.addPlugin(CrashReporterPlugin.getInstance()); 40 | 41 | NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin(); 42 | NetworkingModule.setCustomClientBuilder( 43 | new NetworkingModule.CustomClientBuilder() { 44 | @Override 45 | public void apply(OkHttpClient.Builder builder) { 46 | builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin)); 47 | } 48 | }); 49 | client.addPlugin(networkFlipperPlugin); 50 | client.start(); 51 | 52 | // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized 53 | // Hence we run if after all native modules have been initialized 54 | ReactContext reactContext = reactInstanceManager.getCurrentReactContext(); 55 | if (reactContext == null) { 56 | reactInstanceManager.addReactInstanceEventListener( 57 | new ReactInstanceEventListener() { 58 | @Override 59 | public void onReactContextInitialized(ReactContext reactContext) { 60 | reactInstanceManager.removeReactInstanceEventListener(this); 61 | reactContext.runOnNativeModulesQueueThread( 62 | new Runnable() { 63 | @Override 64 | public void run() { 65 | client.addPlugin(new FrescoFlipperPlugin()); 66 | } 67 | }); 68 | } 69 | }); 70 | } else { 71 | client.addPlugin(new FrescoFlipperPlugin()); 72 | } 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /packages/008/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /packages/008/android/app/src/main/java/com/anonymous/softphone/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.anonymous.softphone; 2 | 3 | import android.os.Build; 4 | import android.os.Bundle; 5 | 6 | import com.facebook.react.ReactActivity; 7 | import com.facebook.react.ReactActivityDelegate; 8 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint; 9 | import com.facebook.react.defaults.DefaultReactActivityDelegate; 10 | 11 | import expo.modules.ReactActivityDelegateWrapper; 12 | 13 | public class MainActivity extends ReactActivity { 14 | @Override 15 | protected void onCreate(Bundle savedInstanceState) { 16 | // Set the theme to AppTheme BEFORE onCreate to support 17 | // coloring the background, status bar, and navigation bar. 18 | // This is required for expo-splash-screen. 19 | setTheme(R.style.AppTheme); 20 | super.onCreate(null); 21 | } 22 | 23 | /** 24 | * Returns the name of the main component registered from JavaScript. 25 | * This is used to schedule rendering of the component. 26 | */ 27 | @Override 28 | protected String getMainComponentName() { 29 | return "main"; 30 | } 31 | 32 | /** 33 | * Returns the instance of the {@link ReactActivityDelegate}. Here we use a util class {@link 34 | * DefaultReactActivityDelegate} which allows you to easily enable Fabric and Concurrent React 35 | * (aka React 18) with two boolean flags. 36 | */ 37 | @Override 38 | protected ReactActivityDelegate createReactActivityDelegate() { 39 | return new ReactActivityDelegateWrapper(this, BuildConfig.IS_NEW_ARCHITECTURE_ENABLED, new DefaultReactActivityDelegate( 40 | this, 41 | getMainComponentName(), 42 | // If you opted-in for the New Architecture, we enable the Fabric Renderer. 43 | DefaultNewArchitectureEntryPoint.getFabricEnabled(), // fabricEnabled 44 | // If you opted-in for the New Architecture, we enable Concurrent React (i.e. React 18). 45 | DefaultNewArchitectureEntryPoint.getConcurrentReactEnabled() // concurrentRootEnabled 46 | )); 47 | } 48 | 49 | /** 50 | * Align the back button behavior with Android S 51 | * where moving root activities to background instead of finishing activities. 52 | * @see onBackPressed 53 | */ 54 | @Override 55 | public void invokeDefaultOnBackPressed() { 56 | if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) { 57 | if (!moveTaskToBack(false)) { 58 | // For non-root activities, use the default implementation to finish them. 59 | super.invokeDefaultOnBackPressed(); 60 | } 61 | return; 62 | } 63 | 64 | // Use the default back button implementation on Android S 65 | // because it's doing more than {@link Activity#moveTaskToBack} in fact. 66 | super.invokeDefaultOnBackPressed(); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /packages/008/android/app/src/main/java/com/anonymous/softphone/MainApplication.java: -------------------------------------------------------------------------------- 1 | package com.anonymous.softphone; 2 | 3 | import android.app.Application; 4 | import android.content.res.Configuration; 5 | import androidx.annotation.NonNull; 6 | 7 | import com.facebook.react.PackageList; 8 | import com.facebook.react.ReactApplication; 9 | import com.facebook.react.ReactNativeHost; 10 | import com.facebook.react.ReactPackage; 11 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint; 12 | import com.facebook.react.defaults.DefaultReactNativeHost; 13 | import com.facebook.soloader.SoLoader; 14 | 15 | import expo.modules.ApplicationLifecycleDispatcher; 16 | import expo.modules.ReactNativeHostWrapper; 17 | 18 | import java.util.List; 19 | 20 | public class MainApplication extends Application implements ReactApplication { 21 | 22 | private final ReactNativeHost mReactNativeHost = 23 | new ReactNativeHostWrapper(this, new DefaultReactNativeHost(this) { 24 | @Override 25 | public boolean getUseDeveloperSupport() { 26 | return BuildConfig.DEBUG; 27 | } 28 | 29 | @Override 30 | protected List getPackages() { 31 | @SuppressWarnings("UnnecessaryLocalVariable") 32 | List packages = new PackageList(this).getPackages(); 33 | // Packages that cannot be autolinked yet can be added manually here, for example: 34 | // packages.add(new MyReactNativePackage()); 35 | return packages; 36 | } 37 | 38 | @Override 39 | protected String getJSMainModuleName() { 40 | return "index"; 41 | } 42 | 43 | @Override 44 | protected boolean isNewArchEnabled() { 45 | return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED; 46 | } 47 | 48 | @Override 49 | protected Boolean isHermesEnabled() { 50 | return BuildConfig.IS_HERMES_ENABLED; 51 | } 52 | }); 53 | 54 | @Override 55 | public ReactNativeHost getReactNativeHost() { 56 | return mReactNativeHost; 57 | } 58 | 59 | @Override 60 | public void onCreate() { 61 | super.onCreate(); 62 | SoLoader.init(this, /* native exopackage */ false); 63 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { 64 | // If you opted-in for the New Architecture, we load the native entry point for this app. 65 | DefaultNewArchitectureEntryPoint.load(); 66 | } 67 | ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); 68 | ApplicationLifecycleDispatcher.onApplicationCreate(this); 69 | } 70 | 71 | @Override 72 | public void onConfigurationChanged(@NonNull Configuration newConfig) { 73 | super.onConfigurationChanged(newConfig); 74 | ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /packages/008/android/app/src/main/res/drawable-hdpi/splashscreen_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/drawable-hdpi/splashscreen_image.png -------------------------------------------------------------------------------- /packages/008/android/app/src/main/res/drawable-mdpi/splashscreen_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/drawable-mdpi/splashscreen_image.png -------------------------------------------------------------------------------- /packages/008/android/app/src/main/res/drawable-xhdpi/splashscreen_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/drawable-xhdpi/splashscreen_image.png -------------------------------------------------------------------------------- /packages/008/android/app/src/main/res/drawable-xxhdpi/splashscreen_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/drawable-xxhdpi/splashscreen_image.png -------------------------------------------------------------------------------- /packages/008/android/app/src/main/res/drawable-xxxhdpi/splashscreen_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/drawable-xxxhdpi/splashscreen_image.png -------------------------------------------------------------------------------- /packages/008/android/app/src/main/res/drawable/rn_edit_text_material.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 21 | 22 | 23 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /packages/008/android/app/src/main/res/drawable/splashscreen.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /packages/008/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/008/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/008/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /packages/008/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /packages/008/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /packages/008/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /packages/008/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /packages/008/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /packages/008/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /packages/008/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /packages/008/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /packages/008/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /packages/008/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /packages/008/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /packages/008/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /packages/008/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /packages/008/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /packages/008/android/app/src/main/res/values-night/colors.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/008/android/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | #ffffff 3 | #ffffff 4 | #023c69 5 | #ffffff 6 | -------------------------------------------------------------------------------- /packages/008/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | softphone 3 | contain 4 | false 5 | -------------------------------------------------------------------------------- /packages/008/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 14 | 17 | -------------------------------------------------------------------------------- /packages/008/android/app/src/release/java/com/anonymous/softphone/ReactNativeFlipper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | *

This source code is licensed under the MIT license found in the LICENSE file in the root 5 | * directory of this source tree. 6 | */ 7 | package com.anonymous.softphone; 8 | 9 | import android.content.Context; 10 | import com.facebook.react.ReactInstanceManager; 11 | 12 | /** 13 | * Class responsible of loading Flipper inside your React Native application. This is the release 14 | * flavor of it so it's empty as we don't want to load Flipper. 15 | */ 16 | public class ReactNativeFlipper { 17 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { 18 | // Do nothing as we don't want to initialize Flipper on Release. 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/008/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 = findProperty('android.buildToolsVersion') ?: '33.0.0' 6 | minSdkVersion = Integer.parseInt(findProperty('android.minSdkVersion') ?: '21') 7 | compileSdkVersion = Integer.parseInt(findProperty('android.compileSdkVersion') ?: '33') 8 | targetSdkVersion = Integer.parseInt(findProperty('android.targetSdkVersion') ?: '33') 9 | if (findProperty('android.kotlinVersion')) { 10 | kotlinVersion = findProperty('android.kotlinVersion') 11 | } 12 | frescoVersion = findProperty('expo.frescoVersion') ?: '2.5.0' 13 | 14 | // We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP. 15 | ndkVersion = "23.1.7779620" 16 | } 17 | repositories { 18 | google() 19 | mavenCentral() 20 | } 21 | dependencies { 22 | classpath('com.android.tools.build:gradle:7.4.1') 23 | classpath('com.facebook.react:react-native-gradle-plugin') 24 | } 25 | } 26 | 27 | allprojects { 28 | repositories { 29 | maven { 30 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 31 | url(new File(['node', '--print', "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), '../android')) 32 | } 33 | maven { 34 | // Android JSC is installed from npm 35 | url(new File(['node', '--print', "require.resolve('jsc-android/package.json')"].execute(null, rootDir).text.trim(), '../dist')) 36 | } 37 | 38 | google() 39 | mavenCentral() 40 | maven { url 'https://www.jitpack.io' } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /packages/008/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: -Xmx512m -XX:MaxMetaspaceSize=256m 13 | org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m 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 | # AndroidX package structure to make it clearer which packages are bundled with the 21 | # Android operating system, and which are packaged with your app's APK 22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 23 | android.useAndroidX=true 24 | 25 | # Automatically convert third-party libraries to use AndroidX 26 | android.enableJetifier=true 27 | 28 | # Version of flipper SDK to use with React Native 29 | FLIPPER_VERSION=0.125.0 30 | 31 | # Use this property to specify which architecture you want to build. 32 | # You can also override it from the CLI using 33 | # ./gradlew -PreactNativeArchitectures=x86_64 34 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64 35 | 36 | # Use this property to enable support to the new architecture. 37 | # This will allow you to use TurboModules and the Fabric render in 38 | # your application. You should enable this flag either if you want 39 | # to write custom TurboModules/Fabric components OR use libraries that 40 | # are providing them. 41 | newArchEnabled=false 42 | 43 | # The hosted JavaScript engine 44 | # Supported values: expo.jsEngine = "hermes" | "jsc" 45 | expo.jsEngine=hermes 46 | 47 | # Enable GIF support in React Native images (~200 B increase) 48 | expo.gif.enabled=true 49 | # Enable webp support in React Native images (~85 KB increase) 50 | expo.webp.enabled=true 51 | # Enable animated webp support (~3.4 MB increase) 52 | # Disabled by default because iOS doesn't support animated webp 53 | expo.webp.animated=false 54 | -------------------------------------------------------------------------------- /packages/008/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /packages/008/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /packages/008/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 https://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 Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if %ERRORLEVEL% equ 0 goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if %ERRORLEVEL% equ 0 goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | set EXIT_CODE=%ERRORLEVEL% 84 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 85 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 86 | exit /b %EXIT_CODE% 87 | 88 | :mainEnd 89 | if "%OS%"=="Windows_NT" endlocal 90 | 91 | :omega 92 | -------------------------------------------------------------------------------- /packages/008/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'softphone' 2 | 3 | apply from: new File(["node", "--print", "require.resolve('expo/package.json')"].execute(null, rootDir).text.trim(), "../scripts/autolinking.gradle"); 4 | useExpoModules() 5 | 6 | apply from: new File(["node", "--print", "require.resolve('@react-native-community/cli-platform-android/package.json')"].execute(null, rootDir).text.trim(), "../native_modules.gradle"); 7 | applyNativeModulesSettingsGradle(settings) 8 | 9 | include ':app' 10 | includeBuild(new File(["node", "--print", "require.resolve('react-native-gradle-plugin/package.json')"].execute(null, rootDir).text.trim()).getParentFile()) 11 | -------------------------------------------------------------------------------- /packages/008/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "008", 4 | "slug": "008", 5 | "version": "1.0.0", 6 | "orientation": "portrait", 7 | "icon": "./assets/icon.png", 8 | "userInterfaceStyle": "light", 9 | "splash": { 10 | "image": "./assets/splash.png", 11 | "resizeMode": "contain", 12 | "backgroundColor": "#f02f65" 13 | }, 14 | "assetBundlePatterns": ["**/*"], 15 | "ios": { 16 | "supportsTablet": true, 17 | "bundleIdentifier": "app.kunzite.008" 18 | }, 19 | "android": { 20 | "adaptiveIcon": { 21 | "foregroundImage": "./assets/adaptive-icon.png", 22 | "backgroundColor": "#ffffff" 23 | }, 24 | "package": "app.kunzite.008" 25 | }, 26 | "web": { 27 | "favicon": "./web/favicon.png" 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packages/008/assets/adaptive-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/assets/adaptive-icon.png -------------------------------------------------------------------------------- /packages/008/assets/fonts/Roboto-Flex.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/assets/fonts/Roboto-Flex.ttf -------------------------------------------------------------------------------- /packages/008/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/assets/icon.png -------------------------------------------------------------------------------- /packages/008/assets/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/assets/splash.png -------------------------------------------------------------------------------- /packages/008/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function (api) { 2 | api.cache(true); 3 | return { 4 | presets: ['babel-preset-expo'] 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /packages/008/cypress.config.js: -------------------------------------------------------------------------------- 1 | const { defineConfig } = require('cypress'); 2 | 3 | module.exports = defineConfig({ 4 | e2e: { 5 | baseUrl: 'http://localhost:19006' 6 | } 7 | }); 8 | -------------------------------------------------------------------------------- /packages/008/cypress/e2e/spec.cy.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable cypress/no-unnecessary-waiting */ 2 | 3 | const TEST_NUMBER = '007'; 4 | const TRANSFER_NUMBER = '008'; 5 | 6 | beforeEach(() => { 7 | cy.visit('/'); 8 | 9 | cy.get('[data-testid="Settings"]').type('cfgDemo008.json'); 10 | cy.get('[data-testid="settingsAccept"]').click(); 11 | cy.wait(2000); 12 | }); 13 | 14 | describe('Outbound Call test', () => { 15 | it('no input does nothing', () => { 16 | cy.get('[data-testid="callButton"]').click(); 17 | }); 18 | 19 | it('Calls number and hangs', () => { 20 | cy.get('[data-testid="dialerTextInput"]').type(TEST_NUMBER); 21 | cy.get('[data-testid="callButton"]').click(); 22 | 23 | cy.wait(1000); 24 | cy.get('[data-testid="hangupButton"]').click(); 25 | }); 26 | 27 | it('Call number and blind transfer', () => { 28 | cy.get('[data-testid="dialerTextInput"]').type(TEST_NUMBER); 29 | cy.get('[data-testid="callButton"]').click(); 30 | 31 | cy.wait(1000); 32 | cy.get('[data-testid="blindTransferButton"]').click(); 33 | 34 | cy.get('[data-testid="transferDialerdialerTextInput"]').type( 35 | TRANSFER_NUMBER 36 | ); 37 | cy.get('[data-testid="transferButton"]').click(); 38 | }); 39 | 40 | it('VideoCall number and hangs', () => { 41 | cy.get('[data-testid="dialerTextInput"]').type(TEST_NUMBER); 42 | cy.get('[data-testid="videoCallButton"]').click(); 43 | 44 | cy.wait(1000); 45 | cy.get('[data-testid="hangupButton"]').click(); 46 | }); 47 | }); 48 | -------------------------------------------------------------------------------- /packages/008/cypress/fixtures/example.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Using fixtures to represent data", 3 | "email": "hello@cypress.io", 4 | "body": "Fixtures are a great way to mock data for responses to routes" 5 | } 6 | -------------------------------------------------------------------------------- /packages/008/cypress/support/commands.js: -------------------------------------------------------------------------------- 1 | // *********************************************** 2 | // This example commands.js shows you how to 3 | // create various custom commands and overwrite 4 | // existing commands. 5 | // 6 | // For more comprehensive examples of custom 7 | // commands please read more here: 8 | // https://on.cypress.io/custom-commands 9 | // *********************************************** 10 | // 11 | // 12 | // -- This is a parent command -- 13 | // Cypress.Commands.add('login', (email, password) => { ... }) 14 | // 15 | // 16 | // -- This is a child command -- 17 | // Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) 18 | // 19 | // 20 | // -- This is a dual command -- 21 | // Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) 22 | // 23 | // 24 | // -- This will overwrite an existing command -- 25 | // Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) 26 | -------------------------------------------------------------------------------- /packages/008/cypress/support/e2e.js: -------------------------------------------------------------------------------- 1 | // *********************************************************** 2 | // This example support/e2e.js is processed and 3 | // loaded automatically before your test files. 4 | // 5 | // This is a great place to put global configuration and 6 | // behavior that modifies Cypress. 7 | // 8 | // You can change the location of this file or turn off 9 | // automatically serving support files with the 10 | // 'supportFile' configuration option. 11 | // 12 | // You can read more here: 13 | // https://on.cypress.io/configuration 14 | // *********************************************************** 15 | 16 | // Import commands.js using ES2015 syntax: 17 | import './commands'; 18 | 19 | // Alternatively you can use CommonJS syntax: 20 | // require('./commands') 21 | -------------------------------------------------------------------------------- /packages/008/index.js: -------------------------------------------------------------------------------- 1 | import { registerRootComponent } from 'expo'; 2 | 3 | import App from './App'; 4 | 5 | // registerRootComponent calls AppRegistry.registerComponent('main', () => App); 6 | // It also ensures that whether you load the app in Expo Go or in a native build, 7 | // the environment is set up appropriately 8 | registerRootComponent(App); 9 | -------------------------------------------------------------------------------- /packages/008/ios/.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 | .xcode.env.local 25 | 26 | # Bundle artifacts 27 | *.jsbundle 28 | 29 | # CocoaPods 30 | /Pods/ 31 | -------------------------------------------------------------------------------- /packages/008/ios/.xcode.env: -------------------------------------------------------------------------------- 1 | # This `.xcode.env` file is versioned and is used to source the environment 2 | # used when running script phases inside Xcode. 3 | # To customize your local environment, you can create an `.xcode.env.local` 4 | # file that is not versioned. 5 | 6 | # NODE_BINARY variable contains the PATH to the node executable. 7 | # 8 | # Customize the NODE_BINARY variable here. 9 | # For example, to use nvm with brew, add the following line 10 | # . "$(brew --prefix nvm)/nvm.sh" --no-use 11 | export NODE_BINARY=$(command -v node) 12 | -------------------------------------------------------------------------------- /packages/008/ios/Podfile: -------------------------------------------------------------------------------- 1 | require File.join(File.dirname(`node --print "require.resolve('expo/package.json')"`), "scripts/autolinking") 2 | require File.join(File.dirname(`node --print "require.resolve('react-native/package.json')"`), "scripts/react_native_pods") 3 | require File.join(File.dirname(`node --print "require.resolve('@react-native-community/cli-platform-ios/package.json')"`), "native_modules") 4 | 5 | require 'json' 6 | podfile_properties = JSON.parse(File.read(File.join(__dir__, 'Podfile.properties.json'))) rescue {} 7 | 8 | ENV['RCT_NEW_ARCH_ENABLED'] = podfile_properties['newArchEnabled'] == 'true' ? '1' : '0' 9 | ENV['EX_DEV_CLIENT_NETWORK_INSPECTOR'] = '1' if podfile_properties['EX_DEV_CLIENT_NETWORK_INSPECTOR'] == 'true' 10 | 11 | platform :ios, podfile_properties['ios.deploymentTarget'] || '13.0' 12 | install! 'cocoapods', 13 | :deterministic_uuids => false 14 | 15 | prepare_react_native_project! 16 | 17 | # If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set. 18 | # because `react-native-flipper` depends on (FlipperKit,...), which will be excluded. To fix this, 19 | # you can also exclude `react-native-flipper` in `react-native.config.js` 20 | # 21 | # ```js 22 | # module.exports = { 23 | # dependencies: { 24 | # ...(process.env.NO_FLIPPER ? { 'react-native-flipper': { platforms: { ios: null } } } : {}), 25 | # } 26 | # } 27 | # ``` 28 | flipper_config = FlipperConfiguration.disabled 29 | if ENV['NO_FLIPPER'] == '1' then 30 | # Explicitly disabled through environment variables 31 | flipper_config = FlipperConfiguration.disabled 32 | elsif podfile_properties.key?('ios.flipper') then 33 | # Configure Flipper in Podfile.properties.json 34 | if podfile_properties['ios.flipper'] == 'true' then 35 | flipper_config = FlipperConfiguration.enabled(["Debug", "Release"]) 36 | elsif podfile_properties['ios.flipper'] != 'false' then 37 | flipper_config = FlipperConfiguration.enabled(["Debug", "Release"], { 'Flipper' => podfile_properties['ios.flipper'] }) 38 | end 39 | end 40 | 41 | target 'softphone' do 42 | use_expo_modules! 43 | config = use_native_modules! 44 | 45 | use_frameworks! :linkage => podfile_properties['ios.useFrameworks'].to_sym if podfile_properties['ios.useFrameworks'] 46 | use_frameworks! :linkage => ENV['USE_FRAMEWORKS'].to_sym if ENV['USE_FRAMEWORKS'] 47 | 48 | # Flags change depending on the env values. 49 | flags = get_default_flags() 50 | 51 | use_react_native!( 52 | :path => config[:reactNativePath], 53 | :hermes_enabled => podfile_properties['expo.jsEngine'] == nil || podfile_properties['expo.jsEngine'] == 'hermes', 54 | :fabric_enabled => flags[:fabric_enabled], 55 | # An absolute path to your application root. 56 | :app_path => "#{Pod::Config.instance.installation_root}/..", 57 | # Note that if you have use_frameworks! enabled, Flipper will not work if enabled 58 | :flipper_configuration => flipper_config 59 | ) 60 | 61 | post_install do |installer| 62 | react_native_post_install( 63 | installer, 64 | config[:reactNativePath], 65 | # Set `mac_catalyst_enabled` to `true` in order to apply patches 66 | # necessary for Mac Catalyst builds 67 | :mac_catalyst_enabled => false 68 | ) 69 | __apply_Xcode_12_5_M1_post_install_workaround(installer) 70 | 71 | # This is necessary for Xcode 14, because it signs resource bundles by default 72 | # when building for devices. 73 | installer.target_installation_results.pod_target_installation_results 74 | .each do |pod_name, target_installation_result| 75 | target_installation_result.resource_bundle_targets.each do |resource_bundle_target| 76 | resource_bundle_target.build_configurations.each do |config| 77 | config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO' 78 | end 79 | end 80 | end 81 | end 82 | 83 | post_integrate do |installer| 84 | begin 85 | expo_patch_react_imports!(installer) 86 | rescue => e 87 | Pod::UI.warn e 88 | end 89 | end 90 | end 91 | -------------------------------------------------------------------------------- /packages/008/ios/Podfile.properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo.jsEngine": "hermes" 3 | } 4 | -------------------------------------------------------------------------------- /packages/008/ios/softphone.xcodeproj/xcshareddata/xcschemes/softphone.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 53 | 55 | 61 | 62 | 63 | 64 | 70 | 72 | 78 | 79 | 80 | 81 | 83 | 84 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /packages/008/ios/softphone/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | 5 | @interface AppDelegate : EXAppDelegateWrapper 6 | 7 | @end 8 | -------------------------------------------------------------------------------- /packages/008/ios/softphone/AppDelegate.mm: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | #import 4 | #import 5 | 6 | @implementation AppDelegate 7 | 8 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 9 | { 10 | self.moduleName = @"main"; 11 | 12 | // You can add your custom initial props in the dictionary below. 13 | // They will be passed down to the ViewController used by React Native. 14 | self.initialProps = @{}; 15 | 16 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 17 | } 18 | 19 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge 20 | { 21 | #if DEBUG 22 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; 23 | #else 24 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 25 | #endif 26 | } 27 | 28 | /// This method controls whether the `concurrentRoot`feature of React18 is turned on or off. 29 | /// 30 | /// @see: https://reactjs.org/blog/2022/03/29/react-v18.html 31 | /// @note: This requires to be rendering on Fabric (i.e. on the New Architecture). 32 | /// @return: `true` if the `concurrentRoot` feature is enabled. Otherwise, it returns `false`. 33 | - (BOOL)concurrentRootEnabled 34 | { 35 | return true; 36 | } 37 | 38 | // Linking API 39 | - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary *)options { 40 | return [super application:application openURL:url options:options] || [RCTLinkingManager application:application openURL:url options:options]; 41 | } 42 | 43 | // Universal Links 44 | - (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray> * _Nullable))restorationHandler { 45 | BOOL result = [RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler]; 46 | return [super application:application continueUserActivity:userActivity restorationHandler:restorationHandler] || result; 47 | } 48 | 49 | // Explicitly define remote notification delegates to ensure compatibility with some third-party libraries 50 | - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken 51 | { 52 | return [super application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; 53 | } 54 | 55 | // Explicitly define remote notification delegates to ensure compatibility with some third-party libraries 56 | - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error 57 | { 58 | return [super application:application didFailToRegisterForRemoteNotificationsWithError:error]; 59 | } 60 | 61 | // Explicitly define remote notification delegates to ensure compatibility with some third-party libraries 62 | - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler 63 | { 64 | return [super application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler]; 65 | } 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-20x20@1x.png -------------------------------------------------------------------------------- /packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-20x20@2x.png -------------------------------------------------------------------------------- /packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-20x20@3x.png -------------------------------------------------------------------------------- /packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-29x29@1x.png -------------------------------------------------------------------------------- /packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-29x29@2x.png -------------------------------------------------------------------------------- /packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-29x29@3x.png -------------------------------------------------------------------------------- /packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-40x40@1x.png -------------------------------------------------------------------------------- /packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-40x40@2x.png -------------------------------------------------------------------------------- /packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-40x40@3x.png -------------------------------------------------------------------------------- /packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-60x60@2x.png -------------------------------------------------------------------------------- /packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-60x60@3x.png -------------------------------------------------------------------------------- /packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-76x76@1x.png -------------------------------------------------------------------------------- /packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-76x76@2x.png -------------------------------------------------------------------------------- /packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-83.5x83.5@2x.png -------------------------------------------------------------------------------- /packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "idiom": "iphone", 5 | "size": "20x20", 6 | "scale": "2x", 7 | "filename": "App-Icon-20x20@2x.png" 8 | }, 9 | { 10 | "idiom": "iphone", 11 | "size": "20x20", 12 | "scale": "3x", 13 | "filename": "App-Icon-20x20@3x.png" 14 | }, 15 | { 16 | "idiom": "iphone", 17 | "size": "29x29", 18 | "scale": "1x", 19 | "filename": "App-Icon-29x29@1x.png" 20 | }, 21 | { 22 | "idiom": "iphone", 23 | "size": "29x29", 24 | "scale": "2x", 25 | "filename": "App-Icon-29x29@2x.png" 26 | }, 27 | { 28 | "idiom": "iphone", 29 | "size": "29x29", 30 | "scale": "3x", 31 | "filename": "App-Icon-29x29@3x.png" 32 | }, 33 | { 34 | "idiom": "iphone", 35 | "size": "40x40", 36 | "scale": "2x", 37 | "filename": "App-Icon-40x40@2x.png" 38 | }, 39 | { 40 | "idiom": "iphone", 41 | "size": "40x40", 42 | "scale": "3x", 43 | "filename": "App-Icon-40x40@3x.png" 44 | }, 45 | { 46 | "idiom": "iphone", 47 | "size": "60x60", 48 | "scale": "2x", 49 | "filename": "App-Icon-60x60@2x.png" 50 | }, 51 | { 52 | "idiom": "iphone", 53 | "size": "60x60", 54 | "scale": "3x", 55 | "filename": "App-Icon-60x60@3x.png" 56 | }, 57 | { 58 | "idiom": "ipad", 59 | "size": "20x20", 60 | "scale": "1x", 61 | "filename": "App-Icon-20x20@1x.png" 62 | }, 63 | { 64 | "idiom": "ipad", 65 | "size": "20x20", 66 | "scale": "2x", 67 | "filename": "App-Icon-20x20@2x.png" 68 | }, 69 | { 70 | "idiom": "ipad", 71 | "size": "29x29", 72 | "scale": "1x", 73 | "filename": "App-Icon-29x29@1x.png" 74 | }, 75 | { 76 | "idiom": "ipad", 77 | "size": "29x29", 78 | "scale": "2x", 79 | "filename": "App-Icon-29x29@2x.png" 80 | }, 81 | { 82 | "idiom": "ipad", 83 | "size": "40x40", 84 | "scale": "1x", 85 | "filename": "App-Icon-40x40@1x.png" 86 | }, 87 | { 88 | "idiom": "ipad", 89 | "size": "40x40", 90 | "scale": "2x", 91 | "filename": "App-Icon-40x40@2x.png" 92 | }, 93 | { 94 | "idiom": "ipad", 95 | "size": "76x76", 96 | "scale": "1x", 97 | "filename": "App-Icon-76x76@1x.png" 98 | }, 99 | { 100 | "idiom": "ipad", 101 | "size": "76x76", 102 | "scale": "2x", 103 | "filename": "App-Icon-76x76@2x.png" 104 | }, 105 | { 106 | "idiom": "ipad", 107 | "size": "83.5x83.5", 108 | "scale": "2x", 109 | "filename": "App-Icon-83.5x83.5@2x.png" 110 | }, 111 | { 112 | "idiom": "ios-marketing", 113 | "size": "1024x1024", 114 | "scale": "1x", 115 | "filename": "ItunesArtwork@2x.png" 116 | } 117 | ], 118 | "info": { 119 | "version": 1, 120 | "author": "expo" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png -------------------------------------------------------------------------------- /packages/008/ios/softphone/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info": { 3 | "version": 1, 4 | "author": "expo" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /packages/008/ios/softphone/Images.xcassets/SplashScreen.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "idiom": "universal", 5 | "filename": "image.png", 6 | "scale": "1x" 7 | }, 8 | { 9 | "idiom": "universal", 10 | "scale": "2x" 11 | }, 12 | { 13 | "idiom": "universal", 14 | "scale": "3x" 15 | } 16 | ], 17 | "info": { 18 | "version": 1, 19 | "author": "expo" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/008/ios/softphone/Images.xcassets/SplashScreen.imageset/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/ios/softphone/Images.xcassets/SplashScreen.imageset/image.png -------------------------------------------------------------------------------- /packages/008/ios/softphone/Images.xcassets/SplashScreenBackground.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "idiom": "universal", 5 | "filename": "image.png", 6 | "scale": "1x" 7 | }, 8 | { 9 | "idiom": "universal", 10 | "scale": "2x" 11 | }, 12 | { 13 | "idiom": "universal", 14 | "scale": "3x" 15 | } 16 | ], 17 | "info": { 18 | "version": 1, 19 | "author": "expo" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/008/ios/softphone/Images.xcassets/SplashScreenBackground.imageset/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/ios/softphone/Images.xcassets/SplashScreenBackground.imageset/image.png -------------------------------------------------------------------------------- /packages/008/ios/softphone/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | softphone 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 19 | CFBundleShortVersionString 20 | 1.0.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleURLTypes 24 | 25 | 26 | CFBundleURLSchemes 27 | 28 | app.kunzite.sotphone 29 | 30 | 31 | 32 | CFBundleVersion 33 | 1 34 | LSRequiresIPhoneOS 35 | 36 | NSAppTransportSecurity 37 | 38 | NSAllowsArbitraryLoads 39 | 40 | NSExceptionDomains 41 | 42 | localhost 43 | 44 | NSExceptionAllowsInsecureHTTPLoads 45 | 46 | 47 | 48 | 49 | UILaunchStoryboardName 50 | SplashScreen 51 | UIRequiredDeviceCapabilities 52 | 53 | armv7 54 | 55 | UIRequiresFullScreen 56 | 57 | UIStatusBarStyle 58 | UIStatusBarStyleDefault 59 | UISupportedInterfaceOrientations 60 | 61 | UIInterfaceOrientationPortrait 62 | UIInterfaceOrientationPortraitUpsideDown 63 | 64 | UISupportedInterfaceOrientations~ipad 65 | 66 | UIInterfaceOrientationPortrait 67 | UIInterfaceOrientationPortraitUpsideDown 68 | UIInterfaceOrientationLandscapeLeft 69 | UIInterfaceOrientationLandscapeRight 70 | 71 | UIUserInterfaceStyle 72 | Light 73 | UIViewControllerBasedStatusBarAppearance 74 | 75 | 76 | -------------------------------------------------------------------------------- /packages/008/ios/softphone/SplashScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /packages/008/ios/softphone/Supporting/Expo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | EXUpdatesCheckOnLaunch 6 | ALWAYS 7 | EXUpdatesEnabled 8 | 9 | EXUpdatesLaunchWaitMs 10 | 0 11 | EXUpdatesSDKVersion 12 | 48.0.0 13 | EXUpdatesURL 14 | https://exp.host/@anonymous/softphone 15 | 16 | -------------------------------------------------------------------------------- /packages/008/ios/softphone/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char * argv[]) { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 8 | } 9 | } 10 | 11 | -------------------------------------------------------------------------------- /packages/008/ios/softphone/noop-file.swift: -------------------------------------------------------------------------------- 1 | // 2 | // @generated 3 | // A blank Swift file must be created for native modules with Swift files to work correctly. 4 | // 5 | -------------------------------------------------------------------------------- /packages/008/ios/softphone/softphone.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | aps-environment 6 | development 7 | 8 | -------------------------------------------------------------------------------- /packages/008/metro.config.js: -------------------------------------------------------------------------------- 1 | // Learn more https://docs.expo.io/guides/customizing-metro 2 | const { getDefaultConfig } = require('expo/metro-config'); 3 | 4 | module.exports = getDefaultConfig(__dirname); 5 | -------------------------------------------------------------------------------- /packages/008/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@kunzite/008", 3 | "description": "Open-source event-driven AI powered Softphone", 4 | "version": "2.2.0", 5 | "license": "AGPL-3.0-only", 6 | "private": true, 7 | "author": { 8 | "name": "Kunzite", 9 | "email": "support@kunzite.app", 10 | "url": "https://kunzite.app" 11 | }, 12 | "repository": "https://github.com/kunzite-app/008", 13 | "bugs": "https://github.com/kunzite-app/008/issues", 14 | "homepage": "./", 15 | "scripts": { 16 | "start": "expo start --dev-client", 17 | "android": "expo run:android", 18 | "ios": "expo run:ios", 19 | "web": "expo start --web", 20 | "build-web": "expo export:web", 21 | "storybook-generate": "sb-rn-get-stories", 22 | "storybook-watch": "sb-rn-watcher", 23 | "storybook-web": "start-storybook -p 6006 -c .storybook-web", 24 | "build-storybook": "build-storybook -c .storybook-web", 25 | "lint": "eslint ./", 26 | "e2e": "yarn web & cypress run" 27 | }, 28 | "dependencies": { 29 | "008Q": "file:../008Q", 30 | "@expo/webpack-config": "^18.0.1", 31 | "@microsoft/applicationinsights-react-js": "^17.0.1", 32 | "@microsoft/applicationinsights-web": "^3.0.3", 33 | "base-64": "^1.0.0", 34 | "crypto-js": "^4.1.1", 35 | "elasticlunr": "^0.9.5", 36 | "expo": "~48.0.18", 37 | "expo-av": "^13.4.1", 38 | "expo-splash-screen": "~0.18.2", 39 | "expo-status-bar": "~1.4.4", 40 | "level": "^8.0.0", 41 | "lodash": "^4.17.21", 42 | "moment": "^2.27.0", 43 | "p-queue": "^7.4.1", 44 | "p-retry": "^6.1.0", 45 | "react": "18.2.0", 46 | "react-dom": "18.2.0", 47 | "react-icons": "^3.10.0", 48 | "react-native": "0.71.8", 49 | "react-native-select-dropdown": "^3.4.0", 50 | "react-native-web": "^0.19.8", 51 | "sip.js": "^0.21.2", 52 | "vcf": "^2.1.1", 53 | "zustand": "^4.5.1" 54 | }, 55 | "devDependencies": { 56 | "@babel/core": "^7.20.0", 57 | "@babel/plugin-proposal-export-namespace-from": "^7.18.9", 58 | "@react-native-async-storage/async-storage": "^1.19.3", 59 | "@react-native-community/datetimepicker": "^7.5.0", 60 | "@react-native-community/slider": "^4.4.3", 61 | "@storybook/addon-actions": "^6.5.16", 62 | "@storybook/addon-controls": "^6.5.16", 63 | "@storybook/addon-essentials": "^6.5", 64 | "@storybook/addon-ondevice-actions": "^6.5.6", 65 | "@storybook/addon-ondevice-controls": "^6.5.6", 66 | "@storybook/addon-react-native-web": "^0.0.21", 67 | "@storybook/builder-webpack5": "^6.5", 68 | "@storybook/manager-webpack5": "^6.5", 69 | "@storybook/react": "^6.5", 70 | "@storybook/react-native": "^6.5.6", 71 | "babel-loader": "^8.3.0", 72 | "babel-plugin-react-native-web": "^0.19.8", 73 | "cypress": "^13.6.0", 74 | "eslint": "^8.49.0", 75 | "eslint-config-universe": "^12.0.0", 76 | "eslint-plugin-cypress": "^2.15.1", 77 | "prettier": "^3.0.3", 78 | "prop-types": "^15.8.1", 79 | "react-native-safe-area-context": "^4.7.1" 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /packages/008/src/008QWorkerLLM.js: -------------------------------------------------------------------------------- 1 | import PQueue from 'p-queue'; 2 | 3 | import { summarize } from '008Q'; 4 | 5 | const QUEUE = new PQueue({ concurrency: 1 }); 6 | 7 | self.addEventListener('message', async ({ data }) => { 8 | const { id, transcription } = data; 9 | console.log(`[008Q] Queuing job ${id}`); 10 | 11 | QUEUE.add(async () => { 12 | console.log('[008Q] Summarizing...'); 13 | try { 14 | const summarization = await summarize({ transcription }); 15 | self.postMessage({ id, summarization }); 16 | } catch (err) { 17 | console.error('[008Q] Error summarizing', err); 18 | self.postMessage({ id, error: err.message }); 19 | } 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /packages/008/src/008QWorkerTTS.js: -------------------------------------------------------------------------------- 1 | import PQueue from 'p-queue'; 2 | 3 | import { transcript, tts } from '008Q'; 4 | 5 | const QUEUE = new PQueue({ concurrency: 5 }); 6 | 7 | self.addEventListener('message', async ({ data }) => { 8 | const { id, audio, wav } = data; 9 | console.log(`[008Q] Queuing job ${id}`); 10 | 11 | QUEUE.add(async () => { 12 | console.log('[008Q] Transcribing...'); 13 | try { 14 | const transcription = await (audio 15 | ? tts({ audio }) 16 | : transcript({ wav })); 17 | self.postMessage({ id, transcription }); 18 | } catch (err) { 19 | console.error('[008Q] Error transcribing', err); 20 | self.postMessage({ id, error: err.message }); 21 | } 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /packages/008/src/Sip.js: -------------------------------------------------------------------------------- 1 | import { 2 | UserAgent, 3 | Registerer, 4 | Inviter, 5 | Invitation, 6 | RegistererState, 7 | Session, 8 | SessionState, 9 | Web 10 | } from 'sip.js'; 11 | 12 | Session.prototype.getStream = function () { 13 | try { 14 | const stream = new MediaStream(); 15 | this.sessionDescriptionHandler?.peerConnection 16 | ?.getReceivers() 17 | .forEach(({ track }) => { 18 | if (track) stream.addTrack(track); 19 | }); 20 | 21 | return stream; 22 | } catch (err) { 23 | console.error(err); 24 | } 25 | }; 26 | 27 | Session.prototype.setMuted = function (muted) { 28 | this._muted = muted; 29 | this.sessionDescriptionHandler?.peerConnection 30 | ?.getLocalStreams() 31 | .forEach(stream => { 32 | stream.getAudioTracks().forEach(track => { 33 | track.enabled = !muted; 34 | }); 35 | }); 36 | }; 37 | 38 | Session.prototype.setMutedVideo = function (muted) { 39 | this._mutedVideo = muted; 40 | this.sessionDescriptionHandler?.peerConnection 41 | ?.getLocalStreams() 42 | .forEach(stream => { 43 | stream.getVideoTracks().forEach(track => { 44 | track.enabled = !muted; 45 | }); 46 | }); 47 | }; 48 | 49 | Session.prototype.hold = async function () { 50 | this.setHold(true); 51 | }; 52 | 53 | Session.prototype.unhold = async function () { 54 | this.setHold(false); 55 | }; 56 | 57 | Session.prototype.setHold = async function (hold) { 58 | this._hold = hold; 59 | 60 | if (this.state !== SessionState.Established) return; 61 | await this.invite({ 62 | sessionDescriptionHandlerModifiers: hold ? [Web.holdModifier] : [] 63 | }); 64 | }; 65 | 66 | Session.prototype.isVideo = function () { 67 | if (this.isInbound()) 68 | return ( 69 | this.request?.body?.includes?.('m=video') || 70 | this.request?.body?.body?.includes?.('m=video') 71 | ); 72 | 73 | return this.sessionDescriptionHandlerOptions.constraints?.video; 74 | }; 75 | 76 | Session.prototype.isInbound = function () { 77 | return this instanceof Invitation; 78 | }; 79 | 80 | Session.prototype.autoanswer = function () { 81 | return this.request?.getHeader('X-Autoanswer'); 82 | }; 83 | 84 | Session.prototype.dtmf = function (key) { 85 | this.info({ 86 | requestOptions: { 87 | body: { 88 | contentDisposition: 'render', 89 | contentType: 'application/dtmf-relay', 90 | content: `Signal=${key}\r\nDuration=1000` 91 | } 92 | } 93 | }); 94 | }; 95 | 96 | export { 97 | UserAgent, 98 | Registerer, 99 | Inviter, 100 | Invitation, 101 | RegistererState, 102 | Session, 103 | SessionState 104 | }; 105 | -------------------------------------------------------------------------------- /packages/008/src/Sound.js: -------------------------------------------------------------------------------- 1 | import { Platform } from 'react-native'; 2 | import { Audio as AVAudio } from 'expo-av'; 3 | 4 | const setSinkId = async ({ audio, deviceId }) => { 5 | await audio?.stopAsync?.(); 6 | audio.pause?.(); 7 | 8 | const speakers = await getSpeakers(); 9 | const speaker = 10 | speakers.find(dev => dev.deviceId === deviceId)?.deviceId || 'default'; 11 | await audio.setSinkId(speaker); 12 | }; 13 | 14 | export default class Sound { 15 | constructor({ media, loop = false } = {}) { 16 | const init = async () => { 17 | if (Platform.OS === 'web') { 18 | this.audio = new Audio(`./assets/sounds/${media}.mp3`); 19 | this.audio.loop = loop; 20 | } else { 21 | const { sound } = await AVAudio.Sound.createAsync( 22 | require(`../web/assets/sounds/${media}.mp3`), 23 | { isLooping: loop } 24 | ); 25 | this.audio = sound; 26 | } 27 | }; 28 | 29 | init(); 30 | } 31 | 32 | async play() { 33 | await setSinkId({ audio: this.audio, deviceId: this.deviceId }); 34 | this.audio?.playAsync?.(); 35 | this.audio?.play?.(); 36 | this.playing = true; 37 | } 38 | 39 | async stop(pause) { 40 | await this.audio?.stopAsync?.(); 41 | this.audio.pause?.(); 42 | 43 | if (!pause) { 44 | await this.audio?.setPositionAsync?.(0); 45 | this.audio.currentTime = 0; 46 | } 47 | 48 | this.playing = false; 49 | } 50 | 51 | async setDevice(deviceId) { 52 | this.deviceId = deviceId; 53 | 54 | if (this.playing) { 55 | this.stop(true); 56 | this.audio.play(); 57 | } 58 | } 59 | } 60 | 61 | export const RING_TONE = new Sound({ 62 | media: `ring`, 63 | loop: true 64 | }); 65 | 66 | export const RING_BACK = new Sound({ 67 | media: `ringback`, 68 | loop: true 69 | }); 70 | 71 | export const REJECT_TONE = new Sound({ 72 | media: `busy`, 73 | loop: true 74 | }); 75 | 76 | export const play_tone = () => { 77 | REJECT_TONE.play(); 78 | setTimeout(() => REJECT_TONE.stop(), 1000); 79 | }; 80 | 81 | export const play_reject = () => { 82 | REJECT_TONE.play(); 83 | setTimeout(() => REJECT_TONE.stop(), 3000); 84 | }; 85 | 86 | export const getSpeakers = async () => { 87 | return getDevices({ kind: 'audiooutput' }); 88 | }; 89 | 90 | export const getMicrophones = async () => { 91 | return getDevices({ kind: 'audioinput' }); 92 | }; 93 | 94 | export const getDevices = async ({ kind }) => { 95 | try { 96 | const devices = await navigator.mediaDevices.enumerateDevices(); 97 | return devices.filter(dev => dev.kind === kind); 98 | } catch (err) { 99 | console.log('Error getting audio devices', err); 100 | } 101 | 102 | return []; 103 | }; 104 | -------------------------------------------------------------------------------- /packages/008/src/components/Addons.jsx: -------------------------------------------------------------------------------- 1 | import { View } from 'react-native'; 2 | 3 | export const AddonsIframe = ({ width, height, url }) => { 4 | return ( 5 | 13 |