├── .watchmanconfig ├── src ├── containers │ ├── Root.js │ ├── ChatScreenContainer.js │ ├── LoginScreenContainer.js │ ├── RecentsScreenContainer.js │ └── RegisterScreenContainer.js ├── utilities │ ├── network │ │ └── README.md │ ├── storage │ │ ├── README.md │ │ └── store.js │ ├── enums │ │ └── Presence.js │ ├── routing │ │ ├── index.js │ │ ├── index.android.js │ │ ├── index.ios.js │ │ └── router.js │ ├── MockData │ │ ├── ContactsMock.js │ │ └── ConversationMock.js │ └── index.js ├── i18n │ ├── af │ │ ├── commons.json │ │ ├── index.js │ │ ├── login.json │ │ ├── register.json │ │ └── chat.json │ ├── ar │ │ ├── commons.json │ │ ├── index.js │ │ ├── login.json │ │ ├── register.json │ │ └── chat.json │ ├── ca │ │ ├── commons.json │ │ ├── login.json │ │ ├── register.json │ │ └── chat.json │ ├── cs │ │ ├── commons.json │ │ ├── login.json │ │ ├── register.json │ │ └── chat.json │ ├── da │ │ ├── commons.json │ │ ├── login.json │ │ ├── register.json │ │ └── chat.json │ ├── de │ │ ├── commons.json │ │ ├── login.json │ │ ├── register.json │ │ └── chat.json │ ├── el │ │ ├── commons.json │ │ ├── login.json │ │ ├── register.json │ │ └── chat.json │ ├── en │ │ ├── commons.json │ │ ├── login.json │ │ ├── index.js │ │ ├── register.json │ │ └── chat.json │ ├── es │ │ ├── commons.json │ │ ├── index.js │ │ ├── login.json │ │ ├── register.json │ │ └── chat.json │ ├── fi │ │ ├── commons.json │ │ ├── login.json │ │ ├── register.json │ │ └── chat.json │ ├── he │ │ ├── commons.json │ │ ├── login.json │ │ ├── register.json │ │ └── chat.json │ ├── hu │ │ ├── commons.json │ │ ├── login.json │ │ ├── register.json │ │ └── chat.json │ ├── it │ │ ├── commons.json │ │ ├── login.json │ │ ├── register.json │ │ └── chat.json │ ├── ja │ │ ├── commons.json │ │ ├── index.js │ │ ├── login.json │ │ ├── register.json │ │ └── chat.json │ ├── ko │ │ ├── commons.json │ │ ├── login.json │ │ ├── register.json │ │ └── chat.json │ ├── nl │ │ ├── commons.json │ │ ├── login.json │ │ ├── register.json │ │ └── chat.json │ ├── no │ │ ├── commons.json │ │ ├── login.json │ │ ├── register.json │ │ └── chat.json │ ├── pl │ │ ├── commons.json │ │ ├── login.json │ │ ├── register.json │ │ └── chat.json │ ├── pt │ │ ├── commons.json │ │ ├── index.js │ │ ├── login.json │ │ ├── register.json │ │ └── chat.json │ ├── ro │ │ ├── commons.json │ │ ├── index.js │ │ ├── login.json │ │ ├── register.json │ │ └── chat.json │ ├── sr │ │ ├── commons.json │ │ ├── index.js │ │ ├── login.json │ │ ├── register.json │ │ └── chat.json │ ├── sv │ │ ├── commons.json │ │ ├── index.js │ │ ├── login.json │ │ ├── register.json │ │ └── chat.json │ ├── tr │ │ ├── commons.json │ │ ├── index.js │ │ ├── login.json │ │ ├── register.json │ │ └── chat.json │ ├── uk │ │ ├── commons.json │ │ ├── index.js │ │ ├── login.json │ │ ├── register.json │ │ └── chat.json │ ├── vi │ │ ├── commons.json │ │ ├── login.json │ │ ├── register.json │ │ └── chat.json │ ├── zh │ │ ├── commons.json │ │ ├── login.json │ │ ├── register.json │ │ └── chat.json │ ├── es-ES │ │ ├── commons.json │ │ ├── login.json │ │ └── register.json │ ├── pt-BR │ │ ├── commons.json │ │ ├── login.json │ │ └── register.json │ ├── pt-PT │ │ ├── commons.json │ │ ├── login.json │ │ └── register.json │ ├── sv-SE │ │ ├── commons.json │ │ ├── login.json │ │ └── register.json │ ├── zh-CN │ │ ├── commons.json │ │ ├── login.json │ │ └── register.json │ ├── zh-TW │ │ ├── commons.json │ │ ├── login.json │ │ └── register.json │ ├── fr │ │ ├── commons.json │ │ ├── index.js │ │ ├── login.json │ │ ├── register.json │ │ └── chat.json │ ├── ru │ │ ├── commons.json │ │ ├── index.js │ │ ├── login.json │ │ ├── register.json │ │ └── chat.json │ └── i18n.js ├── reducers │ ├── uiReducer │ │ ├── types.js │ │ ├── actions.js │ │ ├── index.js │ │ └── reducer.js │ └── rootReducer.js ├── assets │ ├── tox-illustration.png │ ├── playstation-pattern.png │ ├── presence │ │ ├── presence-away.png │ │ ├── presence-busy.png │ │ ├── presence-away@2x.png │ │ ├── presence-busy@2x.png │ │ ├── presence-offline.png │ │ ├── presence-online.png │ │ ├── presence-offline@2x.png │ │ └── presence-online@2x.png │ └── tox-brand-redesign.gvdesign ├── styles │ └── colors.js ├── components │ ├── FormHeader.js │ ├── UserButton.js │ ├── AndroidContextMenu.js │ ├── WelcomePlaceholder.js │ ├── IconButton.js │ ├── RegisterForm.js │ ├── LoginForm.js │ ├── Input.js │ └── ContactItem.js ├── screens │ ├── RegisterScreen.js │ ├── RecentsScreen.js │ └── LoginScreen.js ├── index.js └── stories │ └── index.js ├── .gitattributes ├── app.json ├── android ├── .settings │ └── org.eclipse.buildship.core.prefs ├── app │ ├── .settings │ │ └── org.eclipse.buildship.core.prefs │ ├── src │ │ └── main │ │ │ ├── res │ │ │ ├── values │ │ │ │ ├── strings.xml │ │ │ │ └── styles.xml │ │ │ ├── mipmap-hdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ │ └── ic_launcher.png │ │ │ └── mipmap-xxhdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── assets │ │ │ └── fonts │ │ │ │ ├── Entypo.ttf │ │ │ │ ├── Feather.ttf │ │ │ │ ├── Ionicons.ttf │ │ │ │ ├── Octicons.ttf │ │ │ │ ├── Zocial.ttf │ │ │ │ ├── EvilIcons.ttf │ │ │ │ ├── Foundation.ttf │ │ │ │ ├── FontAwesome.ttf │ │ │ │ ├── MaterialIcons.ttf │ │ │ │ ├── SimpleLineIcons.ttf │ │ │ │ └── MaterialCommunityIcons.ttf │ │ │ ├── java │ │ │ └── com │ │ │ │ └── toxclient │ │ │ │ ├── MainActivity.java │ │ │ │ └── MainApplication.java │ │ │ └── AndroidManifest.xml │ ├── BUCK │ └── proguard-rules.pro ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── keystores │ ├── debug.keystore.properties │ └── BUCK ├── .project ├── settings.gradle ├── build.gradle ├── gradle.properties ├── gradlew.bat └── gradlew ├── .storybook ├── addons.js ├── config.js ├── preview-head.html └── webpack.config.js ├── .babelrc ├── crowdin.yml ├── ios ├── toxclient │ ├── Images.xcassets │ │ ├── Contents.json │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── AppDelegate.h │ ├── main.m │ ├── AppDelegate.m │ ├── Info.plist │ └── Base.lproj │ │ └── LaunchScreen.xib ├── toxclientTests │ ├── Info.plist │ └── toxclientTests.m ├── toxclient-tvOSTests │ └── Info.plist ├── toxclient-tvOS │ └── Info.plist └── toxclient.xcodeproj │ └── xcshareddata │ └── xcschemes │ ├── toxclient.xcscheme │ └── toxclient-tvOS.xcscheme ├── misc └── tox-client-multiple-platforms.png ├── .buckconfig ├── index.js ├── index.windows.js ├── .travis.yml ├── rn-cli.config.js ├── __tests__ └── App.js ├── public ├── styles.global.css ├── manifest.json ├── favicon.ico ├── index.js └── index.html ├── config ├── jest │ ├── fileTransform.js │ └── cssTransform.js ├── polyfills.js ├── paths.js ├── env.js └── webpackDevServer.config.js ├── scripts ├── test.js ├── start.js └── build.js ├── .gitignore ├── License ├── .flowconfig ├── App.js └── CODE_OF_CONDUCT.md /.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /src/containers/Root.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/utilities/network/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/utilities/storage/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "toxclient", 3 | "displayName": "toxclient" 4 | } -------------------------------------------------------------------------------- /src/i18n/af/commons.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultAppTitle": "Konv - Modern secure Instant Messaging" 3 | } -------------------------------------------------------------------------------- /src/i18n/ar/commons.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultAppTitle": "Konv - Modern secure Instant Messaging" 3 | } -------------------------------------------------------------------------------- /src/i18n/ca/commons.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultAppTitle": "Konv - Modern secure Instant Messaging" 3 | } -------------------------------------------------------------------------------- /src/i18n/cs/commons.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultAppTitle": "Konv - Modern secure Instant Messaging" 3 | } -------------------------------------------------------------------------------- /src/i18n/da/commons.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultAppTitle": "Konv - Modern secure Instant Messaging" 3 | } -------------------------------------------------------------------------------- /src/i18n/de/commons.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultAppTitle": "Konv - Modern secure Instant Messaging" 3 | } -------------------------------------------------------------------------------- /src/i18n/el/commons.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultAppTitle": "Konv - Modern secure Instant Messaging" 3 | } -------------------------------------------------------------------------------- /src/i18n/en/commons.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultAppTitle": "Konv - Modern secure Instant Messaging" 3 | } -------------------------------------------------------------------------------- /src/i18n/es/commons.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultAppTitle": "Konv - Modern secure Instant Messaging" 3 | } -------------------------------------------------------------------------------- /src/i18n/fi/commons.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultAppTitle": "Konv - Modern secure Instant Messaging" 3 | } -------------------------------------------------------------------------------- /src/i18n/he/commons.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultAppTitle": "Konv - Modern secure Instant Messaging" 3 | } -------------------------------------------------------------------------------- /src/i18n/hu/commons.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultAppTitle": "Konv - Modern secure Instant Messaging" 3 | } -------------------------------------------------------------------------------- /src/i18n/it/commons.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultAppTitle": "Konv - Modern secure Instant Messaging" 3 | } -------------------------------------------------------------------------------- /src/i18n/ja/commons.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultAppTitle": "Konv - Modern secure Instant Messaging" 3 | } -------------------------------------------------------------------------------- /src/i18n/ko/commons.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultAppTitle": "Konv - Modern secure Instant Messaging" 3 | } -------------------------------------------------------------------------------- /src/i18n/nl/commons.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultAppTitle": "Konv - Modern secure Instant Messaging" 3 | } -------------------------------------------------------------------------------- /src/i18n/no/commons.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultAppTitle": "Konv - Modern secure Instant Messaging" 3 | } -------------------------------------------------------------------------------- /src/i18n/pl/commons.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultAppTitle": "Konv - Modern secure Instant Messaging" 3 | } -------------------------------------------------------------------------------- /src/i18n/pt/commons.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultAppTitle": "Konv - Modern secure Instant Messaging" 3 | } -------------------------------------------------------------------------------- /src/i18n/ro/commons.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultAppTitle": "Konv - Modern secure Instant Messaging" 3 | } -------------------------------------------------------------------------------- /src/i18n/sr/commons.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultAppTitle": "Konv - Modern secure Instant Messaging" 3 | } -------------------------------------------------------------------------------- /src/i18n/sv/commons.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultAppTitle": "Konv - Modern secure Instant Messaging" 3 | } -------------------------------------------------------------------------------- /src/i18n/tr/commons.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultAppTitle": "Konv - Modern güvenli Anında Mesajlaşma" 3 | } -------------------------------------------------------------------------------- /src/i18n/uk/commons.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultAppTitle": "Konv - Modern secure Instant Messaging" 3 | } -------------------------------------------------------------------------------- /src/i18n/vi/commons.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultAppTitle": "Konv - Modern secure Instant Messaging" 3 | } -------------------------------------------------------------------------------- /src/i18n/zh/commons.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultAppTitle": "Konv - Modern secure Instant Messaging" 3 | } -------------------------------------------------------------------------------- /src/reducers/uiReducer/types.js: -------------------------------------------------------------------------------- 1 | export const LOGIN_ANIMATION_RAN = "ui/LOGIN_ANIMATION_RAN"; 2 | -------------------------------------------------------------------------------- /src/i18n/es-ES/commons.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultAppTitle": "Konv - Modern secure Instant Messaging" 3 | } -------------------------------------------------------------------------------- /src/i18n/pt-BR/commons.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultAppTitle": "Konv - Modern secure Instant Messaging" 3 | } -------------------------------------------------------------------------------- /src/i18n/pt-PT/commons.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultAppTitle": "Konv - Modern secure Instant Messaging" 3 | } -------------------------------------------------------------------------------- /src/i18n/sv-SE/commons.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultAppTitle": "Konv - Modern secure Instant Messaging" 3 | } -------------------------------------------------------------------------------- /src/i18n/zh-CN/commons.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultAppTitle": "Konv - Modern secure Instant Messaging" 3 | } -------------------------------------------------------------------------------- /src/i18n/zh-TW/commons.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultAppTitle": "Konv - Modern secure Instant Messaging" 3 | } -------------------------------------------------------------------------------- /android/.settings/org.eclipse.buildship.core.prefs: -------------------------------------------------------------------------------- 1 | #Mon Feb 26 11:56:21 CET 2018 2 | connection.project.dir= 3 | -------------------------------------------------------------------------------- /src/i18n/fr/commons.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultAppTitle": "Konv - Messagerie instantanée moderne et sécurisée" 3 | } -------------------------------------------------------------------------------- /.storybook/addons.js: -------------------------------------------------------------------------------- 1 | import '@storybook/addon-actions/register'; 2 | import '@storybook/addon-links/register'; 3 | -------------------------------------------------------------------------------- /android/app/.settings/org.eclipse.buildship.core.prefs: -------------------------------------------------------------------------------- 1 | #Mon Feb 26 11:56:40 CET 2018 2 | connection.project.dir=.. 3 | -------------------------------------------------------------------------------- /src/assets/tox-illustration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheToxProject/client/HEAD/src/assets/tox-illustration.png -------------------------------------------------------------------------------- /src/i18n/ru/commons.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultAppTitle": "Konv - Современный и безопасный обмен мгновенными сообщениями" 3 | } -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "react", "react-native"], 3 | "plugins": ["transform-object-rest-spread"] 4 | } 5 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | toxclient 3 | 4 | -------------------------------------------------------------------------------- /src/assets/playstation-pattern.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheToxProject/client/HEAD/src/assets/playstation-pattern.png -------------------------------------------------------------------------------- /crowdin.yml: -------------------------------------------------------------------------------- 1 | files: 2 | - source: /src/i18n/en/*.json 3 | translation: /src/i18n/%two_letters_code%/%original_file_name% 4 | -------------------------------------------------------------------------------- /ios/toxclient/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /misc/tox-client-multiple-platforms.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheToxProject/client/HEAD/misc/tox-client-multiple-platforms.png -------------------------------------------------------------------------------- /src/assets/presence/presence-away.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheToxProject/client/HEAD/src/assets/presence/presence-away.png -------------------------------------------------------------------------------- /src/assets/presence/presence-busy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheToxProject/client/HEAD/src/assets/presence/presence-busy.png -------------------------------------------------------------------------------- /src/assets/tox-brand-redesign.gvdesign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheToxProject/client/HEAD/src/assets/tox-brand-redesign.gvdesign -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheToxProject/client/HEAD/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /src/assets/presence/presence-away@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheToxProject/client/HEAD/src/assets/presence/presence-away@2x.png -------------------------------------------------------------------------------- /src/assets/presence/presence-busy@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheToxProject/client/HEAD/src/assets/presence/presence-busy@2x.png -------------------------------------------------------------------------------- /src/assets/presence/presence-offline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheToxProject/client/HEAD/src/assets/presence/presence-offline.png -------------------------------------------------------------------------------- /src/assets/presence/presence-online.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheToxProject/client/HEAD/src/assets/presence/presence-online.png -------------------------------------------------------------------------------- /src/assets/presence/presence-offline@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheToxProject/client/HEAD/src/assets/presence/presence-offline@2x.png -------------------------------------------------------------------------------- /src/assets/presence/presence-online@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheToxProject/client/HEAD/src/assets/presence/presence-online@2x.png -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/Entypo.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheToxProject/client/HEAD/android/app/src/main/assets/fonts/Entypo.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/Feather.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheToxProject/client/HEAD/android/app/src/main/assets/fonts/Feather.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/Ionicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheToxProject/client/HEAD/android/app/src/main/assets/fonts/Ionicons.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/Octicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheToxProject/client/HEAD/android/app/src/main/assets/fonts/Octicons.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/Zocial.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheToxProject/client/HEAD/android/app/src/main/assets/fonts/Zocial.ttf -------------------------------------------------------------------------------- /.buckconfig: -------------------------------------------------------------------------------- 1 | 2 | [android] 3 | target = Google Inc.:Google APIs:23 4 | 5 | [maven_repositories] 6 | central = https://repo1.maven.org/maven2 7 | -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/EvilIcons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheToxProject/client/HEAD/android/app/src/main/assets/fonts/EvilIcons.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/Foundation.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheToxProject/client/HEAD/android/app/src/main/assets/fonts/Foundation.ttf -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import { AppRegistry } from "react-native"; 2 | import App from "./App"; 3 | 4 | AppRegistry.registerComponent("toxclient", () => App); 5 | -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/FontAwesome.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheToxProject/client/HEAD/android/app/src/main/assets/fonts/FontAwesome.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/MaterialIcons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheToxProject/client/HEAD/android/app/src/main/assets/fonts/MaterialIcons.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/SimpleLineIcons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheToxProject/client/HEAD/android/app/src/main/assets/fonts/SimpleLineIcons.ttf -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheToxProject/client/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheToxProject/client/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheToxProject/client/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/utilities/enums/Presence.js: -------------------------------------------------------------------------------- 1 | const Presence = { 2 | OFFLINE: -1, 3 | ONLINE: 0, 4 | AWAY: 1, 5 | BUSY: 2 6 | }; 7 | 8 | export default Presence; 9 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheToxProject/client/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/keystores/debug.keystore.properties: -------------------------------------------------------------------------------- 1 | key.store=debug.keystore 2 | key.alias=androiddebugkey 3 | key.store.password=android 4 | key.alias.password=android 5 | -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/MaterialCommunityIcons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheToxProject/client/HEAD/android/app/src/main/assets/fonts/MaterialCommunityIcons.ttf -------------------------------------------------------------------------------- /.storybook/config.js: -------------------------------------------------------------------------------- 1 | import { configure } from '@storybook/react'; 2 | 3 | function loadStories() { 4 | require('../src/stories'); 5 | } 6 | 7 | configure(loadStories, module); 8 | -------------------------------------------------------------------------------- /index.windows.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { AppRegistry } from "react-native"; 3 | import App from "./App"; 4 | 5 | AppRegistry.registerComponent("toxclient", () => App); 6 | -------------------------------------------------------------------------------- /src/reducers/uiReducer/actions.js: -------------------------------------------------------------------------------- 1 | import * as types from "./types"; 2 | 3 | export const loginAnimationDone = () => { 4 | return { 5 | type: types.LOGIN_ANIMATION_RAN 6 | }; 7 | }; 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | cache: yarn 3 | 4 | node_js: 5 | - "7.0.0" 6 | - "8.0.0" 7 | - "8.8.1" 8 | 9 | script: yarn build 10 | after_success: yarn storybook:deploy -- --ci -------------------------------------------------------------------------------- /src/utilities/routing/index.js: -------------------------------------------------------------------------------- 1 | import * as Routing from "react-router-dom"; 2 | export default Routing; 3 | export const Router = Routing.BrowserRouter; 4 | export const Switch = Routing.Switch; 5 | -------------------------------------------------------------------------------- /android/keystores/BUCK: -------------------------------------------------------------------------------- 1 | keystore( 2 | name = "debug", 3 | properties = "debug.keystore.properties", 4 | store = "debug.keystore", 5 | visibility = [ 6 | "PUBLIC", 7 | ], 8 | ) 9 | -------------------------------------------------------------------------------- /src/utilities/routing/index.android.js: -------------------------------------------------------------------------------- 1 | import * as Routing from "react-router-native"; 2 | export default Routing; 3 | export const Router = Routing.NativeRouter; 4 | export const Switch = Routing.Switch; 5 | -------------------------------------------------------------------------------- /src/utilities/routing/index.ios.js: -------------------------------------------------------------------------------- 1 | import * as Routing from "react-router-native"; 2 | export default Routing; 3 | export const Router = Routing.NativeRouter; 4 | export const Switch = Routing.Switch; 5 | -------------------------------------------------------------------------------- /src/i18n/af/index.js: -------------------------------------------------------------------------------- 1 | import commons from "./commons.json"; 2 | import login from "./login.json"; 3 | import register from "./register.json"; 4 | 5 | export default { 6 | commons, 7 | login, 8 | register 9 | }; 10 | -------------------------------------------------------------------------------- /src/i18n/ar/index.js: -------------------------------------------------------------------------------- 1 | import commons from "./commons.json"; 2 | import login from "./login.json"; 3 | import register from "./register.json"; 4 | 5 | export default { 6 | commons, 7 | login, 8 | register 9 | }; 10 | -------------------------------------------------------------------------------- /src/i18n/es/index.js: -------------------------------------------------------------------------------- 1 | import commons from "./commons.json"; 2 | import login from "./login.json"; 3 | import register from "./register.json"; 4 | 5 | export default { 6 | commons, 7 | login, 8 | register 9 | }; 10 | -------------------------------------------------------------------------------- /src/i18n/ja/index.js: -------------------------------------------------------------------------------- 1 | import commons from "./commons.json"; 2 | import login from "./login.json"; 3 | import register from "./register.json"; 4 | 5 | export default { 6 | commons, 7 | login, 8 | register 9 | }; 10 | -------------------------------------------------------------------------------- /src/i18n/pt/index.js: -------------------------------------------------------------------------------- 1 | import commons from "./commons.json"; 2 | import login from "./login.json"; 3 | import register from "./register.json"; 4 | 5 | export default { 6 | commons, 7 | login, 8 | register 9 | }; 10 | -------------------------------------------------------------------------------- /src/i18n/ro/index.js: -------------------------------------------------------------------------------- 1 | import commons from "./commons.json"; 2 | import login from "./login.json"; 3 | import register from "./register.json"; 4 | 5 | export default { 6 | commons, 7 | login, 8 | register 9 | }; 10 | -------------------------------------------------------------------------------- /src/i18n/ru/index.js: -------------------------------------------------------------------------------- 1 | import commons from "./commons.json"; 2 | import login from "./login.json"; 3 | import register from "./register.json"; 4 | 5 | export default { 6 | commons, 7 | login, 8 | register 9 | }; 10 | -------------------------------------------------------------------------------- /src/i18n/sr/index.js: -------------------------------------------------------------------------------- 1 | import commons from "./commons.json"; 2 | import login from "./login.json"; 3 | import register from "./register.json"; 4 | 5 | export default { 6 | commons, 7 | login, 8 | register 9 | }; 10 | -------------------------------------------------------------------------------- /src/i18n/sv/index.js: -------------------------------------------------------------------------------- 1 | import commons from "./commons.json"; 2 | import login from "./login.json"; 3 | import register from "./register.json"; 4 | 5 | export default { 6 | commons, 7 | login, 8 | register 9 | }; 10 | -------------------------------------------------------------------------------- /src/i18n/tr/index.js: -------------------------------------------------------------------------------- 1 | import commons from "./commons.json"; 2 | import login from "./login.json"; 3 | import register from "./register.json"; 4 | 5 | export default { 6 | commons, 7 | login, 8 | register 9 | }; 10 | -------------------------------------------------------------------------------- /src/i18n/uk/index.js: -------------------------------------------------------------------------------- 1 | import commons from "./commons.json"; 2 | import login from "./login.json"; 3 | import register from "./register.json"; 4 | 5 | export default { 6 | commons, 7 | login, 8 | register 9 | }; 10 | -------------------------------------------------------------------------------- /rn-cli.config.js: -------------------------------------------------------------------------------- 1 | const blacklist = require("metro/src/blacklist"); 2 | 3 | module.exports = { 4 | getBlacklistRE: function() { 5 | return blacklist([new RegExp(/.*\/__fixtures__\/.*/)]); // Ignore the electron dist folder. 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /src/reducers/uiReducer/index.js: -------------------------------------------------------------------------------- 1 | import Reducer from "./reducer"; 2 | import Actions from "./actions"; 3 | import Types from "./types"; 4 | 5 | export default { 6 | reducer: Reducer, 7 | actions: Actions, 8 | types: Types 9 | }; 10 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip 6 | -------------------------------------------------------------------------------- /src/i18n/af/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Glad to see you back! 🤘", 3 | "fields": { 4 | "username": "Username...", 5 | "password": "Password..." 6 | }, 7 | "actions": { 8 | "login": "Login", 9 | "register": "Create a profile" 10 | } 11 | } -------------------------------------------------------------------------------- /src/i18n/ar/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Glad to see you back! 🤘", 3 | "fields": { 4 | "username": "Username...", 5 | "password": "Password..." 6 | }, 7 | "actions": { 8 | "login": "Login", 9 | "register": "Create a profile" 10 | } 11 | } -------------------------------------------------------------------------------- /src/i18n/ca/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Glad to see you back! 🤘", 3 | "fields": { 4 | "username": "Username...", 5 | "password": "Password..." 6 | }, 7 | "actions": { 8 | "login": "Login", 9 | "register": "Create a profile" 10 | } 11 | } -------------------------------------------------------------------------------- /src/i18n/cs/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Glad to see you back! 🤘", 3 | "fields": { 4 | "username": "Username...", 5 | "password": "Password..." 6 | }, 7 | "actions": { 8 | "login": "Login", 9 | "register": "Create a profile" 10 | } 11 | } -------------------------------------------------------------------------------- /src/i18n/da/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Glad to see you back! 🤘", 3 | "fields": { 4 | "username": "Username...", 5 | "password": "Password..." 6 | }, 7 | "actions": { 8 | "login": "Login", 9 | "register": "Create a profile" 10 | } 11 | } -------------------------------------------------------------------------------- /src/i18n/de/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Glad to see you back! 🤘", 3 | "fields": { 4 | "username": "Username...", 5 | "password": "Password..." 6 | }, 7 | "actions": { 8 | "login": "Login", 9 | "register": "Create a profile" 10 | } 11 | } -------------------------------------------------------------------------------- /src/i18n/el/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Glad to see you back! 🤘", 3 | "fields": { 4 | "username": "Username...", 5 | "password": "Password..." 6 | }, 7 | "actions": { 8 | "login": "Login", 9 | "register": "Create a profile" 10 | } 11 | } -------------------------------------------------------------------------------- /src/i18n/en/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Glad to see you back! 🤘", 3 | "fields": { 4 | "username": "Username...", 5 | "password": "Password..." 6 | }, 7 | "actions": { 8 | "login": "Login", 9 | "register": "Create a profile" 10 | } 11 | } -------------------------------------------------------------------------------- /src/i18n/es/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Glad to see you back! 🤘", 3 | "fields": { 4 | "username": "Username...", 5 | "password": "Password..." 6 | }, 7 | "actions": { 8 | "login": "Login", 9 | "register": "Create a profile" 10 | } 11 | } -------------------------------------------------------------------------------- /src/i18n/fi/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Glad to see you back! 🤘", 3 | "fields": { 4 | "username": "Username...", 5 | "password": "Password..." 6 | }, 7 | "actions": { 8 | "login": "Login", 9 | "register": "Create a profile" 10 | } 11 | } -------------------------------------------------------------------------------- /src/i18n/he/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Glad to see you back! 🤘", 3 | "fields": { 4 | "username": "Username...", 5 | "password": "Password..." 6 | }, 7 | "actions": { 8 | "login": "Login", 9 | "register": "Create a profile" 10 | } 11 | } -------------------------------------------------------------------------------- /src/i18n/hu/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Glad to see you back! 🤘", 3 | "fields": { 4 | "username": "Username...", 5 | "password": "Password..." 6 | }, 7 | "actions": { 8 | "login": "Login", 9 | "register": "Create a profile" 10 | } 11 | } -------------------------------------------------------------------------------- /src/i18n/it/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Glad to see you back! 🤘", 3 | "fields": { 4 | "username": "Username...", 5 | "password": "Password..." 6 | }, 7 | "actions": { 8 | "login": "Login", 9 | "register": "Create a profile" 10 | } 11 | } -------------------------------------------------------------------------------- /src/i18n/ja/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Glad to see you back! 🤘", 3 | "fields": { 4 | "username": "Username...", 5 | "password": "Password..." 6 | }, 7 | "actions": { 8 | "login": "Login", 9 | "register": "Create a profile" 10 | } 11 | } -------------------------------------------------------------------------------- /src/i18n/ko/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Glad to see you back! 🤘", 3 | "fields": { 4 | "username": "Username...", 5 | "password": "Password..." 6 | }, 7 | "actions": { 8 | "login": "Login", 9 | "register": "Create a profile" 10 | } 11 | } -------------------------------------------------------------------------------- /src/i18n/nl/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Glad to see you back! 🤘", 3 | "fields": { 4 | "username": "Username...", 5 | "password": "Password..." 6 | }, 7 | "actions": { 8 | "login": "Login", 9 | "register": "Create a profile" 10 | } 11 | } -------------------------------------------------------------------------------- /src/i18n/no/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Glad to see you back! 🤘", 3 | "fields": { 4 | "username": "Username...", 5 | "password": "Password..." 6 | }, 7 | "actions": { 8 | "login": "Login", 9 | "register": "Create a profile" 10 | } 11 | } -------------------------------------------------------------------------------- /src/i18n/pl/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Glad to see you back! 🤘", 3 | "fields": { 4 | "username": "Username...", 5 | "password": "Password..." 6 | }, 7 | "actions": { 8 | "login": "Login", 9 | "register": "Create a profile" 10 | } 11 | } -------------------------------------------------------------------------------- /src/i18n/pt/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Glad to see you back! 🤘", 3 | "fields": { 4 | "username": "Username...", 5 | "password": "Password..." 6 | }, 7 | "actions": { 8 | "login": "Login", 9 | "register": "Create a profile" 10 | } 11 | } -------------------------------------------------------------------------------- /src/i18n/ro/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Glad to see you back! 🤘", 3 | "fields": { 4 | "username": "Username...", 5 | "password": "Password..." 6 | }, 7 | "actions": { 8 | "login": "Login", 9 | "register": "Create a profile" 10 | } 11 | } -------------------------------------------------------------------------------- /src/i18n/sr/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Glad to see you back! 🤘", 3 | "fields": { 4 | "username": "Username...", 5 | "password": "Password..." 6 | }, 7 | "actions": { 8 | "login": "Login", 9 | "register": "Create a profile" 10 | } 11 | } -------------------------------------------------------------------------------- /src/i18n/sv/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Glad to see you back! 🤘", 3 | "fields": { 4 | "username": "Username...", 5 | "password": "Password..." 6 | }, 7 | "actions": { 8 | "login": "Login", 9 | "register": "Create a profile" 10 | } 11 | } -------------------------------------------------------------------------------- /src/i18n/uk/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Glad to see you back! 🤘", 3 | "fields": { 4 | "username": "Username...", 5 | "password": "Password..." 6 | }, 7 | "actions": { 8 | "login": "Login", 9 | "register": "Create a profile" 10 | } 11 | } -------------------------------------------------------------------------------- /src/i18n/vi/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Glad to see you back! 🤘", 3 | "fields": { 4 | "username": "Username...", 5 | "password": "Password..." 6 | }, 7 | "actions": { 8 | "login": "Login", 9 | "register": "Create a profile" 10 | } 11 | } -------------------------------------------------------------------------------- /src/i18n/zh/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Glad to see you back! 🤘", 3 | "fields": { 4 | "username": "Username...", 5 | "password": "Password..." 6 | }, 7 | "actions": { 8 | "login": "Login", 9 | "register": "Create a profile" 10 | } 11 | } -------------------------------------------------------------------------------- /src/i18n/es-ES/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Glad to see you back! 🤘", 3 | "fields": { 4 | "username": "Username...", 5 | "password": "Password..." 6 | }, 7 | "actions": { 8 | "login": "Login", 9 | "register": "Create a profile" 10 | } 11 | } -------------------------------------------------------------------------------- /src/i18n/pt-BR/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Glad to see you back! 🤘", 3 | "fields": { 4 | "username": "Username...", 5 | "password": "Password..." 6 | }, 7 | "actions": { 8 | "login": "Login", 9 | "register": "Create a profile" 10 | } 11 | } -------------------------------------------------------------------------------- /src/i18n/pt-PT/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Glad to see you back! 🤘", 3 | "fields": { 4 | "username": "Username...", 5 | "password": "Password..." 6 | }, 7 | "actions": { 8 | "login": "Login", 9 | "register": "Create a profile" 10 | } 11 | } -------------------------------------------------------------------------------- /src/i18n/sv-SE/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Glad to see you back! 🤘", 3 | "fields": { 4 | "username": "Username...", 5 | "password": "Password..." 6 | }, 7 | "actions": { 8 | "login": "Login", 9 | "register": "Create a profile" 10 | } 11 | } -------------------------------------------------------------------------------- /src/i18n/zh-CN/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Glad to see you back! 🤘", 3 | "fields": { 4 | "username": "Username...", 5 | "password": "Password..." 6 | }, 7 | "actions": { 8 | "login": "Login", 9 | "register": "Create a profile" 10 | } 11 | } -------------------------------------------------------------------------------- /src/i18n/zh-TW/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Glad to see you back! 🤘", 3 | "fields": { 4 | "username": "Username...", 5 | "password": "Password..." 6 | }, 7 | "actions": { 8 | "login": "Login", 9 | "register": "Create a profile" 10 | } 11 | } -------------------------------------------------------------------------------- /src/i18n/en/index.js: -------------------------------------------------------------------------------- 1 | import commons from "./commons.json"; 2 | import login from "./login.json"; 3 | import register from "./register.json"; 4 | import chat from "./chat.json"; 5 | 6 | export default { 7 | commons, 8 | login, 9 | register, 10 | chat 11 | }; 12 | -------------------------------------------------------------------------------- /src/i18n/fr/index.js: -------------------------------------------------------------------------------- 1 | import commons from "./commons.json"; 2 | import login from "./login.json"; 3 | import register from "./register.json"; 4 | import chat from "./chat.json"; 5 | 6 | export default { 7 | commons, 8 | login, 9 | register, 10 | chat 11 | }; 12 | -------------------------------------------------------------------------------- /src/i18n/ru/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Мы рады, что вы вернулись! 🤘", 3 | "fields": { 4 | "username": "Имя пользователя...", 5 | "password": "Пароль..." 6 | }, 7 | "actions": { 8 | "login": "Вход", 9 | "register": "Создать профиль" 10 | } 11 | } -------------------------------------------------------------------------------- /src/i18n/fr/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Ravis de vous revoir! 🤘", 3 | "fields": { 4 | "username": "Nom d'utilisateur...", 5 | "password": "Mot de passe..." 6 | }, 7 | "actions": { 8 | "login": "Se connecter", 9 | "register": "Créer un profil" 10 | } 11 | } -------------------------------------------------------------------------------- /src/i18n/tr/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Seni tekrar gördüğüme çok sevindim! 🤘", 3 | "fields": { 4 | "username": "Kullanıcı adı...", 5 | "password": "Şifre..." 6 | }, 7 | "actions": { 8 | "login": "Giriş Yap", 9 | "register": "Profil oluştur" 10 | } 11 | } -------------------------------------------------------------------------------- /src/reducers/rootReducer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by amoghbanta on 04/02/17. 3 | */ 4 | import { combineReducers } from "redux"; 5 | import UIReducer from "./uiReducer/index"; 6 | 7 | //this is the list of final reducers 8 | export default combineReducers({ 9 | ui: UIReducer.reducer 10 | }); 11 | -------------------------------------------------------------------------------- /__tests__/App.js: -------------------------------------------------------------------------------- 1 | import 'react-native'; 2 | import React from 'react'; 3 | import App from '../App'; 4 | 5 | // Note: test renderer must be required after react-native. 6 | import renderer from 'react-test-renderer'; 7 | 8 | it('renders correctly', () => { 9 | const tree = renderer.create( 10 | 11 | ); 12 | }); 13 | -------------------------------------------------------------------------------- /src/i18n/af/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Create your Tox profile 🤠", 3 | "fields": { 4 | "username": "Choose your username...", 5 | "password": "Type your password...", 6 | "password_confirm": "Confirm your password..." 7 | }, 8 | "actions": { 9 | "register": "Register", 10 | "login": "Back to login" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/ar/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Create your Tox profile 🤠", 3 | "fields": { 4 | "username": "Choose your username...", 5 | "password": "Type your password...", 6 | "password_confirm": "Confirm your password..." 7 | }, 8 | "actions": { 9 | "register": "Register", 10 | "login": "Back to login" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/ca/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Create your Tox profile 🤠", 3 | "fields": { 4 | "username": "Choose your username...", 5 | "password": "Type your password...", 6 | "password_confirm": "Confirm your password..." 7 | }, 8 | "actions": { 9 | "register": "Register", 10 | "login": "Back to login" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/cs/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Create your Tox profile 🤠", 3 | "fields": { 4 | "username": "Choose your username...", 5 | "password": "Type your password...", 6 | "password_confirm": "Confirm your password..." 7 | }, 8 | "actions": { 9 | "register": "Register", 10 | "login": "Back to login" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/da/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Create your Tox profile 🤠", 3 | "fields": { 4 | "username": "Choose your username...", 5 | "password": "Type your password...", 6 | "password_confirm": "Confirm your password..." 7 | }, 8 | "actions": { 9 | "register": "Register", 10 | "login": "Back to login" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/de/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Create your Tox profile 🤠", 3 | "fields": { 4 | "username": "Choose your username...", 5 | "password": "Type your password...", 6 | "password_confirm": "Confirm your password..." 7 | }, 8 | "actions": { 9 | "register": "Register", 10 | "login": "Back to login" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/el/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Create your Tox profile 🤠", 3 | "fields": { 4 | "username": "Choose your username...", 5 | "password": "Type your password...", 6 | "password_confirm": "Confirm your password..." 7 | }, 8 | "actions": { 9 | "register": "Register", 10 | "login": "Back to login" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/en/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Create your Tox profile 🤠", 3 | "fields": { 4 | "username": "Choose your username...", 5 | "password": "Type your password...", 6 | "password_confirm": "Confirm your password..." 7 | }, 8 | "actions": { 9 | "register": "Register", 10 | "login": "Back to login" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/es/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Create your Tox profile 🤠", 3 | "fields": { 4 | "username": "Choose your username...", 5 | "password": "Type your password...", 6 | "password_confirm": "Confirm your password..." 7 | }, 8 | "actions": { 9 | "register": "Register", 10 | "login": "Back to login" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/fi/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Create your Tox profile 🤠", 3 | "fields": { 4 | "username": "Choose your username...", 5 | "password": "Type your password...", 6 | "password_confirm": "Confirm your password..." 7 | }, 8 | "actions": { 9 | "register": "Register", 10 | "login": "Back to login" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/he/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Create your Tox profile 🤠", 3 | "fields": { 4 | "username": "Choose your username...", 5 | "password": "Type your password...", 6 | "password_confirm": "Confirm your password..." 7 | }, 8 | "actions": { 9 | "register": "Register", 10 | "login": "Back to login" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/hu/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Create your Tox profile 🤠", 3 | "fields": { 4 | "username": "Choose your username...", 5 | "password": "Type your password...", 6 | "password_confirm": "Confirm your password..." 7 | }, 8 | "actions": { 9 | "register": "Register", 10 | "login": "Back to login" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/it/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Create your Tox profile 🤠", 3 | "fields": { 4 | "username": "Choose your username...", 5 | "password": "Type your password...", 6 | "password_confirm": "Confirm your password..." 7 | }, 8 | "actions": { 9 | "register": "Register", 10 | "login": "Back to login" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/ja/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Create your Tox profile 🤠", 3 | "fields": { 4 | "username": "Choose your username...", 5 | "password": "Type your password...", 6 | "password_confirm": "Confirm your password..." 7 | }, 8 | "actions": { 9 | "register": "Register", 10 | "login": "Back to login" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/ko/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Create your Tox profile 🤠", 3 | "fields": { 4 | "username": "Choose your username...", 5 | "password": "Type your password...", 6 | "password_confirm": "Confirm your password..." 7 | }, 8 | "actions": { 9 | "register": "Register", 10 | "login": "Back to login" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/nl/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Create your Tox profile 🤠", 3 | "fields": { 4 | "username": "Choose your username...", 5 | "password": "Type your password...", 6 | "password_confirm": "Confirm your password..." 7 | }, 8 | "actions": { 9 | "register": "Register", 10 | "login": "Back to login" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/no/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Create your Tox profile 🤠", 3 | "fields": { 4 | "username": "Choose your username...", 5 | "password": "Type your password...", 6 | "password_confirm": "Confirm your password..." 7 | }, 8 | "actions": { 9 | "register": "Register", 10 | "login": "Back to login" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/pl/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Create your Tox profile 🤠", 3 | "fields": { 4 | "username": "Choose your username...", 5 | "password": "Type your password...", 6 | "password_confirm": "Confirm your password..." 7 | }, 8 | "actions": { 9 | "register": "Register", 10 | "login": "Back to login" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/pt/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Create your Tox profile 🤠", 3 | "fields": { 4 | "username": "Choose your username...", 5 | "password": "Type your password...", 6 | "password_confirm": "Confirm your password..." 7 | }, 8 | "actions": { 9 | "register": "Register", 10 | "login": "Back to login" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/ro/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Create your Tox profile 🤠", 3 | "fields": { 4 | "username": "Choose your username...", 5 | "password": "Type your password...", 6 | "password_confirm": "Confirm your password..." 7 | }, 8 | "actions": { 9 | "register": "Register", 10 | "login": "Back to login" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/sr/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Create your Tox profile 🤠", 3 | "fields": { 4 | "username": "Choose your username...", 5 | "password": "Type your password...", 6 | "password_confirm": "Confirm your password..." 7 | }, 8 | "actions": { 9 | "register": "Register", 10 | "login": "Back to login" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/sv/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Create your Tox profile 🤠", 3 | "fields": { 4 | "username": "Choose your username...", 5 | "password": "Type your password...", 6 | "password_confirm": "Confirm your password..." 7 | }, 8 | "actions": { 9 | "register": "Register", 10 | "login": "Back to login" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/uk/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Create your Tox profile 🤠", 3 | "fields": { 4 | "username": "Choose your username...", 5 | "password": "Type your password...", 6 | "password_confirm": "Confirm your password..." 7 | }, 8 | "actions": { 9 | "register": "Register", 10 | "login": "Back to login" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/vi/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Create your Tox profile 🤠", 3 | "fields": { 4 | "username": "Choose your username...", 5 | "password": "Type your password...", 6 | "password_confirm": "Confirm your password..." 7 | }, 8 | "actions": { 9 | "register": "Register", 10 | "login": "Back to login" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/zh/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Create your Tox profile 🤠", 3 | "fields": { 4 | "username": "Choose your username...", 5 | "password": "Type your password...", 6 | "password_confirm": "Confirm your password..." 7 | }, 8 | "actions": { 9 | "register": "Register", 10 | "login": "Back to login" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/es-ES/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Create your Tox profile 🤠", 3 | "fields": { 4 | "username": "Choose your username...", 5 | "password": "Type your password...", 6 | "password_confirm": "Confirm your password..." 7 | }, 8 | "actions": { 9 | "register": "Register", 10 | "login": "Back to login" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/pt-BR/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Create your Tox profile 🤠", 3 | "fields": { 4 | "username": "Choose your username...", 5 | "password": "Type your password...", 6 | "password_confirm": "Confirm your password..." 7 | }, 8 | "actions": { 9 | "register": "Register", 10 | "login": "Back to login" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/pt-PT/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Create your Tox profile 🤠", 3 | "fields": { 4 | "username": "Choose your username...", 5 | "password": "Type your password...", 6 | "password_confirm": "Confirm your password..." 7 | }, 8 | "actions": { 9 | "register": "Register", 10 | "login": "Back to login" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/ru/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Создайте свой Tox-профиль 🤠", 3 | "fields": { 4 | "username": "Выберите имя пользователя...", 5 | "password": "Введите пароль...", 6 | "password_confirm": "Подтвердите ваш пароль..." 7 | }, 8 | "actions": { 9 | "register": "Зарегистрироваться", 10 | "login": "Назад" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/sv-SE/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Create your Tox profile 🤠", 3 | "fields": { 4 | "username": "Choose your username...", 5 | "password": "Type your password...", 6 | "password_confirm": "Confirm your password..." 7 | }, 8 | "actions": { 9 | "register": "Register", 10 | "login": "Back to login" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/zh-CN/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Create your Tox profile 🤠", 3 | "fields": { 4 | "username": "Choose your username...", 5 | "password": "Type your password...", 6 | "password_confirm": "Confirm your password..." 7 | }, 8 | "actions": { 9 | "register": "Register", 10 | "login": "Back to login" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/zh-TW/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Create your Tox profile 🤠", 3 | "fields": { 4 | "username": "Choose your username...", 5 | "password": "Type your password...", 6 | "password_confirm": "Confirm your password..." 7 | }, 8 | "actions": { 9 | "register": "Register", 10 | "login": "Back to login" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/tr/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Tox profilinizi oluşturun 🤠", 3 | "fields": { 4 | "username": "Kullanıcı adınızı seçin...", 5 | "password": "Parolanızı yazın...", 6 | "password_confirm": "Parolanızı doğrulayın..." 7 | }, 8 | "actions": { 9 | "register": "Üye ol", 10 | "login": "Giriş ekranına geri dönün" 11 | } 12 | } -------------------------------------------------------------------------------- /public/styles.global.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css?family=Roboto"); 2 | 3 | html, 4 | body { 5 | margin: 0; 6 | padding: 0; 7 | } 8 | 9 | #root { 10 | height: 100vh; 11 | } 12 | 13 | * { 14 | outline: none !important; 15 | font-family: "Roboto", sans-serif; 16 | } 17 | 18 | a { 19 | text-decoration: none !important; 20 | } 21 | -------------------------------------------------------------------------------- /src/i18n/af/chat.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "welcome_back": "Welcome back on Tox! 😘", 4 | "info_text": "Create a conversation or select a contact to start" 5 | }, 6 | "labels": { 7 | "back_button": "Back", 8 | "start_video_call": "Video Call", 9 | "start_audio_call": "Audio Call", 10 | "more_infos": "More informations" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/ar/chat.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "welcome_back": "Welcome back on Tox! 😘", 4 | "info_text": "Create a conversation or select a contact to start" 5 | }, 6 | "labels": { 7 | "back_button": "Back", 8 | "start_video_call": "Video Call", 9 | "start_audio_call": "Audio Call", 10 | "more_infos": "More informations" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/ca/chat.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "welcome_back": "Welcome back on Tox! 😘", 4 | "info_text": "Create a conversation or select a contact to start" 5 | }, 6 | "labels": { 7 | "back_button": "Back", 8 | "start_video_call": "Video Call", 9 | "start_audio_call": "Audio Call", 10 | "more_infos": "More informations" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/cs/chat.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "welcome_back": "Welcome back on Tox! 😘", 4 | "info_text": "Create a conversation or select a contact to start" 5 | }, 6 | "labels": { 7 | "back_button": "Back", 8 | "start_video_call": "Video Call", 9 | "start_audio_call": "Audio Call", 10 | "more_infos": "More informations" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/da/chat.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "welcome_back": "Welcome back on Tox! 😘", 4 | "info_text": "Create a conversation or select a contact to start" 5 | }, 6 | "labels": { 7 | "back_button": "Back", 8 | "start_video_call": "Video Call", 9 | "start_audio_call": "Audio Call", 10 | "more_infos": "More informations" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/de/chat.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "welcome_back": "Welcome back on Tox! 😘", 4 | "info_text": "Create a conversation or select a contact to start" 5 | }, 6 | "labels": { 7 | "back_button": "Back", 8 | "start_video_call": "Video Call", 9 | "start_audio_call": "Audio Call", 10 | "more_infos": "More informations" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/el/chat.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "welcome_back": "Welcome back on Tox! 😘", 4 | "info_text": "Create a conversation or select a contact to start" 5 | }, 6 | "labels": { 7 | "back_button": "Back", 8 | "start_video_call": "Video Call", 9 | "start_audio_call": "Audio Call", 10 | "more_infos": "More informations" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/es/chat.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "welcome_back": "Welcome back on Tox! 😘", 4 | "info_text": "Create a conversation or select a contact to start" 5 | }, 6 | "labels": { 7 | "back_button": "Back", 8 | "start_video_call": "Video Call", 9 | "start_audio_call": "Audio Call", 10 | "more_infos": "More informations" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/fi/chat.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "welcome_back": "Welcome back on Tox! 😘", 4 | "info_text": "Create a conversation or select a contact to start" 5 | }, 6 | "labels": { 7 | "back_button": "Back", 8 | "start_video_call": "Video Call", 9 | "start_audio_call": "Audio Call", 10 | "more_infos": "More informations" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/he/chat.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "welcome_back": "Welcome back on Tox! 😘", 4 | "info_text": "Create a conversation or select a contact to start" 5 | }, 6 | "labels": { 7 | "back_button": "Back", 8 | "start_video_call": "Video Call", 9 | "start_audio_call": "Audio Call", 10 | "more_infos": "More informations" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/hu/chat.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "welcome_back": "Welcome back on Tox! 😘", 4 | "info_text": "Create a conversation or select a contact to start" 5 | }, 6 | "labels": { 7 | "back_button": "Back", 8 | "start_video_call": "Video Call", 9 | "start_audio_call": "Audio Call", 10 | "more_infos": "More informations" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/it/chat.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "welcome_back": "Welcome back on Tox! 😘", 4 | "info_text": "Create a conversation or select a contact to start" 5 | }, 6 | "labels": { 7 | "back_button": "Back", 8 | "start_video_call": "Video Call", 9 | "start_audio_call": "Audio Call", 10 | "more_infos": "More informations" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/ja/chat.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "welcome_back": "Welcome back on Tox! 😘", 4 | "info_text": "Create a conversation or select a contact to start" 5 | }, 6 | "labels": { 7 | "back_button": "Back", 8 | "start_video_call": "Video Call", 9 | "start_audio_call": "Audio Call", 10 | "more_infos": "More informations" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/ko/chat.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "welcome_back": "Welcome back on Tox! 😘", 4 | "info_text": "Create a conversation or select a contact to start" 5 | }, 6 | "labels": { 7 | "back_button": "Back", 8 | "start_video_call": "Video Call", 9 | "start_audio_call": "Audio Call", 10 | "more_infos": "More informations" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/nl/chat.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "welcome_back": "Welcome back on Tox! 😘", 4 | "info_text": "Create a conversation or select a contact to start" 5 | }, 6 | "labels": { 7 | "back_button": "Back", 8 | "start_video_call": "Video Call", 9 | "start_audio_call": "Audio Call", 10 | "more_infos": "More informations" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/no/chat.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "welcome_back": "Welcome back on Tox! 😘", 4 | "info_text": "Create a conversation or select a contact to start" 5 | }, 6 | "labels": { 7 | "back_button": "Back", 8 | "start_video_call": "Video Call", 9 | "start_audio_call": "Audio Call", 10 | "more_infos": "More informations" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/pl/chat.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "welcome_back": "Welcome back on Tox! 😘", 4 | "info_text": "Create a conversation or select a contact to start" 5 | }, 6 | "labels": { 7 | "back_button": "Back", 8 | "start_video_call": "Video Call", 9 | "start_audio_call": "Audio Call", 10 | "more_infos": "More informations" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/pt/chat.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "welcome_back": "Welcome back on Tox! 😘", 4 | "info_text": "Create a conversation or select a contact to start" 5 | }, 6 | "labels": { 7 | "back_button": "Back", 8 | "start_video_call": "Video Call", 9 | "start_audio_call": "Audio Call", 10 | "more_infos": "More informations" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/ro/chat.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "welcome_back": "Welcome back on Tox! 😘", 4 | "info_text": "Create a conversation or select a contact to start" 5 | }, 6 | "labels": { 7 | "back_button": "Back", 8 | "start_video_call": "Video Call", 9 | "start_audio_call": "Audio Call", 10 | "more_infos": "More informations" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/sr/chat.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "welcome_back": "Welcome back on Tox! 😘", 4 | "info_text": "Create a conversation or select a contact to start" 5 | }, 6 | "labels": { 7 | "back_button": "Back", 8 | "start_video_call": "Video Call", 9 | "start_audio_call": "Audio Call", 10 | "more_infos": "More informations" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/sv/chat.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "welcome_back": "Welcome back on Tox! 😘", 4 | "info_text": "Create a conversation or select a contact to start" 5 | }, 6 | "labels": { 7 | "back_button": "Back", 8 | "start_video_call": "Video Call", 9 | "start_audio_call": "Audio Call", 10 | "more_infos": "More informations" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/tr/chat.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "welcome_back": "Welcome back on Tox! 😘", 4 | "info_text": "Create a conversation or select a contact to start" 5 | }, 6 | "labels": { 7 | "back_button": "Back", 8 | "start_video_call": "Video Call", 9 | "start_audio_call": "Audio Call", 10 | "more_infos": "More informations" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/uk/chat.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "welcome_back": "Welcome back on Tox! 😘", 4 | "info_text": "Create a conversation or select a contact to start" 5 | }, 6 | "labels": { 7 | "back_button": "Back", 8 | "start_video_call": "Video Call", 9 | "start_audio_call": "Audio Call", 10 | "more_infos": "More informations" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/vi/chat.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "welcome_back": "Welcome back on Tox! 😘", 4 | "info_text": "Create a conversation or select a contact to start" 5 | }, 6 | "labels": { 7 | "back_button": "Back", 8 | "start_video_call": "Video Call", 9 | "start_audio_call": "Audio Call", 10 | "more_infos": "More informations" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/zh/chat.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "welcome_back": "Welcome back on Tox! 😘", 4 | "info_text": "Create a conversation or select a contact to start" 5 | }, 6 | "labels": { 7 | "back_button": "Back", 8 | "start_video_call": "Video Call", 9 | "start_audio_call": "Audio Call", 10 | "more_infos": "More informations" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/en/chat.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "welcome_back": "Welcome back on Tox! 😘", 4 | "info_text": "Create a conversation or select a contact to start" 5 | }, 6 | "labels": { 7 | "back_button": "Back", 8 | "start_video_call": "Video Call", 9 | "start_audio_call": "Audio Call", 10 | "more_infos": "More informations" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/i18n/ru/chat.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "welcome_back": "С возвращением в Tox! 😘", 4 | "info_text": "Создайте беседу или выберите контакт, чтобы начать" 5 | }, 6 | "labels": { 7 | "back_button": "Назад", 8 | "start_video_call": "Видеозвонок", 9 | "start_audio_call": "Аудиозвонок", 10 | "more_infos": "Подробная информация" 11 | } 12 | } -------------------------------------------------------------------------------- /src/i18n/fr/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": "Créer un profil Tox 🤠", 3 | "fields": { 4 | "username": "Choisissez un nom d'utilisateur...", 5 | "password": "Entrez votre mot de passe...", 6 | "password_confirm": "Confirmez votre mot de passe..." 7 | }, 8 | "actions": { 9 | "register": "S’inscrire", 10 | "login": "J'ai déjà un profil" 11 | } 12 | } -------------------------------------------------------------------------------- /config/jest/fileTransform.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | 5 | // This is a custom Jest transformer turning file imports into filenames. 6 | // http://facebook.github.io/jest/docs/en/webpack.html 7 | 8 | module.exports = { 9 | process(src, filename) { 10 | return `module.exports = ${JSON.stringify(path.basename(filename))};`; 11 | }, 12 | }; 13 | -------------------------------------------------------------------------------- /src/i18n/fr/chat.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "welcome_back": "Bon retour sur Tox! 😘", 4 | "info_text": "Créez une conversation ou sélectionnez un contact pour démarrer" 5 | }, 6 | "labels": { 7 | "back_button": "Retour", 8 | "start_video_call": "Appel Vidéo", 9 | "start_audio_call": "Appel Audio", 10 | "more_infos": "Plus d'informations" 11 | } 12 | } -------------------------------------------------------------------------------- /config/jest/cssTransform.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // This is a custom Jest transformer turning style imports into empty objects. 4 | // http://facebook.github.io/jest/docs/en/webpack.html 5 | 6 | module.exports = { 7 | process() { 8 | return 'module.exports = {};'; 9 | }, 10 | getCacheKey() { 11 | // The output is always the same. 12 | return 'cssTransform'; 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Konv", 3 | "name": "Konv - Modern secure Instant Messaging", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#414141" 15 | } 16 | -------------------------------------------------------------------------------- /.storybook/preview-head.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/utilities/storage/store.js: -------------------------------------------------------------------------------- 1 | import {createStore, applyMiddleware, compose} from "redux"; 2 | import thunk from "redux-thunk"; 3 | import rootReducer from "../../reducers/rootReducer"; 4 | 5 | let initialState = {}; 6 | const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; 7 | const store = createStore(rootReducer, initialState, composeEnhancers(applyMiddleware(thunk))); 8 | 9 | export default store; -------------------------------------------------------------------------------- /src/reducers/uiReducer/reducer.js: -------------------------------------------------------------------------------- 1 | import * as types from "./types"; 2 | 3 | const initialState = { 4 | loginAnimationRan: false 5 | }; 6 | 7 | export default function uiReducer(state = initialState, action) { 8 | switch (action.type) { 9 | case types.LOGIN_ANIMATION_RAN: 10 | return { 11 | ...state, 12 | loginAnimationRan: true 13 | }; 14 | default: 15 | return state; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/toxclient/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.toxclient; 2 | 3 | import com.facebook.react.ReactActivity; 4 | 5 | public class MainActivity extends ReactActivity { 6 | 7 | /** 8 | * Returns the name of the main component registered from JavaScript. 9 | * This is used to schedule rendering of the component. 10 | */ 11 | @Override 12 | protected String getMainComponentName() { 13 | return "toxclient"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/styles/colors.js: -------------------------------------------------------------------------------- 1 | const Colors = { 2 | PRIMARY: "#9C27B0", 3 | LIGHT_PRIMARY: "#E1BEE7", 4 | DARK_PRIMARY: "#7B1FA2", 5 | ACCENT: "rgb(62, 79, 175)", 6 | DARKER_ACCENT: "rgb(46, 59, 131)", 7 | PRIMARY_TEXT: "#212121", 8 | SECONDARY_TEXT: "#757575", 9 | DIVIDE: "#BDBDBD", 10 | ICONS: "#FFFFFF", 11 | TEXT: "#FFFFFF", 12 | BACKGROUND: "#FFFFFF", 13 | DARK_BACKGROUND: "#414141", 14 | DARKER_BACKGROUND: "#333333", 15 | ACTIVE_ITEM: "#ccc" 16 | }; 17 | 18 | module.exports = Colors; 19 | -------------------------------------------------------------------------------- /android/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | toxclient 4 | Project toxclient created by Buildship. 5 | 6 | 7 | 8 | 9 | org.eclipse.buildship.core.gradleprojectbuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.buildship.core.gradleprojectnature 16 | 17 | 18 | -------------------------------------------------------------------------------- /ios/toxclient/AppDelegate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | 12 | @interface AppDelegate : UIResponder 13 | 14 | @property (nonatomic, strong) UIWindow *window; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /src/utilities/routing/router.js: -------------------------------------------------------------------------------- 1 | import { Platform } from "react-native"; 2 | 3 | const RouterPackage = 4 | Platform.OS === "web" 5 | ? require("react-router-dom") 6 | : require("react-router-native"); 7 | 8 | /* 9 | * Remove Platform specific exports :/ 10 | * */ 11 | export const { Link, Route, Redirect, withRouter } = RouterPackage; 12 | export const BackButton = 13 | Platform.OS === "web" ? props => props.children : RouterPackage.BackButton; 14 | export const Router = 15 | Platform.OS === "web" 16 | ? RouterPackage.BrowserRouter 17 | : RouterPackage.NativeRouter; 18 | -------------------------------------------------------------------------------- /ios/toxclient/main.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | 12 | #import "AppDelegate.h" 13 | 14 | int main(int argc, char * argv[]) { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'toxclient' 2 | include ':react-native-vector-icons' 3 | project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android') 4 | include ':react-native-vector-icons' 5 | project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android') 6 | include ':react-native-vector-icons' 7 | project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android') 8 | 9 | include ':app' 10 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:2.2.3' 9 | 10 | // NOTE: Do not place your application dependencies here; they belong 11 | // in the individual module build.gradle files 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | mavenLocal() 18 | jcenter() 19 | maven { 20 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 21 | url "$rootDir/../node_modules/react-native/android" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/containers/ChatScreenContainer.js: -------------------------------------------------------------------------------- 1 | import { connect } from "react-redux"; 2 | import { translate } from "react-i18next"; 3 | 4 | import { withRouter } from "./../utilities/routing/router"; 5 | import ChatScreen from "../screens/ChatScreen"; 6 | //import * as actions from "./../reducers/uiReducer/actions"; 7 | 8 | const mapStateToProps = state => { 9 | return { 10 | //loginAnimationRan: state.ui.loginAnimationRan 11 | }; 12 | }; 13 | 14 | const mapDispatchToProps = dispatch => { 15 | return { 16 | /*loginAnimationDone: () => { 17 | dispatch(actions.loginAnimationDone()); 18 | }*/ 19 | }; 20 | }; 21 | 22 | export default withRouter( 23 | translate(["chat"], { wait: true })( 24 | connect(mapStateToProps, mapDispatchToProps)(ChatScreen) 25 | ) 26 | ); 27 | -------------------------------------------------------------------------------- /src/containers/LoginScreenContainer.js: -------------------------------------------------------------------------------- 1 | import { connect } from "react-redux"; 2 | import { translate } from "react-i18next"; 3 | 4 | import { withRouter } from "./../utilities/routing/router"; 5 | import LoginScreen from "./../screens/LoginScreen"; 6 | import * as actions from "./../reducers/uiReducer/actions"; 7 | 8 | const mapStateToProps = state => { 9 | return { 10 | loginAnimationRan: state.ui.loginAnimationRan 11 | }; 12 | }; 13 | 14 | const mapDispatchToProps = dispatch => { 15 | return { 16 | loginAnimationDone: () => { 17 | dispatch(actions.loginAnimationDone()); 18 | } 19 | }; 20 | }; 21 | 22 | export default withRouter( 23 | translate(["login"], { wait: true })( 24 | connect(mapStateToProps, mapDispatchToProps)(LoginScreen) 25 | ) 26 | ); 27 | -------------------------------------------------------------------------------- /ios/toxclient/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /src/containers/RecentsScreenContainer.js: -------------------------------------------------------------------------------- 1 | import { connect } from "react-redux"; 2 | import { translate } from "react-i18next"; 3 | 4 | import { withRouter } from "./../utilities/routing/router"; 5 | import RecentsScreen from "./../screens/RecentsScreen"; 6 | //import * as actions from "./../reducers/uiReducer/actions"; 7 | 8 | const mapStateToProps = state => { 9 | return { 10 | //loginAnimationRan: state.ui.loginAnimationRan 11 | }; 12 | }; 13 | 14 | const mapDispatchToProps = dispatch => { 15 | return { 16 | /*loginAnimationDone: () => { 17 | dispatch(actions.loginAnimationDone()); 18 | }*/ 19 | }; 20 | }; 21 | 22 | export default withRouter( 23 | translate(["recents"], { wait: true })( 24 | connect(mapStateToProps, mapDispatchToProps)(RecentsScreen) 25 | ) 26 | ); 27 | -------------------------------------------------------------------------------- /src/components/FormHeader.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import { Platform, Text } from "react-native"; 3 | 4 | export class FormHeader extends Component { 5 | render() { 6 | const { text } = this.props; 7 | 8 | /** 9 | * TODO: Handle variant (color: white, black, muted, colors). 10 | */ 11 | return {text}; 12 | } 13 | } 14 | 15 | const styles = { 16 | header: { 17 | color: "rgba(255,255,255,.87)", 18 | fontSize: 22, 19 | marginBottom: 8, 20 | paddingBottom: 12, 21 | textAlign: "center", 22 | ...Platform.select({ 23 | default: { 24 | borderBottomColor: "rgba(255, 255, 255, .3)", 25 | borderBottomWidth: 2 26 | } 27 | }) 28 | } 29 | }; 30 | 31 | export default FormHeader; 32 | -------------------------------------------------------------------------------- /src/containers/RegisterScreenContainer.js: -------------------------------------------------------------------------------- 1 | import { connect } from "react-redux"; 2 | import { translate } from "react-i18next"; 3 | 4 | import { withRouter } from "./../utilities/routing/router"; 5 | import RegisterScreen from "./../screens/RegisterScreen"; 6 | //import * as actions from "./../reducers/uiReducer/actions"; 7 | 8 | const mapStateToProps = state => { 9 | return { 10 | //loginAnimationRan: state.ui.loginAnimationRan 11 | }; 12 | }; 13 | 14 | const mapDispatchToProps = dispatch => { 15 | return { 16 | /*loginAnimationDone: () => { 17 | dispatch(actions.loginAnimationDone()); 18 | }*/ 19 | }; 20 | }; 21 | 22 | export default withRouter( 23 | translate(["register"], { wait: true })( 24 | connect(mapStateToProps, mapDispatchToProps)(RegisterScreen) 25 | ) 26 | ); 27 | -------------------------------------------------------------------------------- /scripts/test.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | // Do this as the first thing so that any code reading it knows the right env. 4 | process.env.BABEL_ENV = "test"; 5 | process.env.NODE_ENV = "test"; 6 | process.env.PUBLIC_URL = ""; 7 | 8 | // Makes the script crash on unhandled rejections instead of silently 9 | // ignoring them. In the future, promise rejections that are not handled will 10 | // terminate the Node.js process with a non-zero exit code. 11 | process.on("unhandledRejection", err => { 12 | throw err; 13 | }); 14 | 15 | // Ensure environment variables are read. 16 | require("../config/env"); 17 | 18 | const jest = require("jest"); 19 | const argv = process.argv.slice(2); 20 | 21 | // Watch unless on CI or in coverage mode 22 | if (!process.env.CI && argv.indexOf("--coverage") < 0) { 23 | argv.push("--watch"); 24 | } 25 | 26 | jest.run(argv); 27 | -------------------------------------------------------------------------------- /ios/toxclientTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /ios/toxclient-tvOSTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /config/polyfills.js: -------------------------------------------------------------------------------- 1 | if (typeof Promise === "undefined") { 2 | // Rejection tracking prevents a common issue where React gets into an 3 | // inconsistent state due to an error, but it gets swallowed by a Promise, 4 | // and the user has no idea what causes React's erratic future behavior. 5 | require("promise/lib/rejection-tracking").enable(); 6 | window.Promise = require("promise/lib/es6-extensions.js"); 7 | } 8 | 9 | // fetch() polyfill for making API calls. 10 | //require('whatwg-fetch'); 11 | 12 | // Object.assign() is commonly used with React. 13 | // It will use the native implementation if it's present and isn't buggy. 14 | Object.assign = require("object-assign"); 15 | 16 | // In tests, polyfill requestAnimationFrame since jsdom doesn't provide it yet. 17 | // We don't polyfill it in the browser--this is user's responsibility. 18 | if (process.env.NODE_ENV === "test") { 19 | require("raf").polyfill(global); 20 | } 21 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | android.useDeprecatedNdk=true 21 | -------------------------------------------------------------------------------- /src/screens/RegisterScreen.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { StyleSheet, View, StatusBar } from "react-native"; 3 | import RegisterForm from "../components/RegisterForm"; 4 | 5 | import Colors from "./../styles/colors"; 6 | 7 | export class RegisterScreen extends React.Component { 8 | render() { 9 | const { t } = this.props; 10 | 11 | return ( 12 | 13 | 19 | 20 | 21 | ); 22 | } 23 | } 24 | 25 | const styles = StyleSheet.create({ 26 | container: { 27 | display: "flex", 28 | flex: 1, 29 | height: "100%", 30 | flexDirection: "column", 31 | justifyContent: "center", 32 | alignItems: "center", 33 | paddingHorizontal: 16, 34 | paddingVertical: 8, 35 | backgroundColor: Colors.DARK_BACKGROUND 36 | } 37 | }); 38 | 39 | export default RegisterScreen; 40 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- 1 |  h(    ���������������������������������������������������������������������������������r���|����������������������x���������������������������������������������s���v���v���y���z�â��������������������������������}��F2�ϼ���qc���s�˳���F3����������������������������������������������l]��|o��rc��r�θ������Ŧ����������������������Ƨ���jZ��pa��xk��uf�̵��˴���hY��|o��hX��n_�ʱ���������������~q���y�̳����v���s�����ɱ��λ�������}p���{��ÿ��|o���|��������������te��tf��se�����п���dR��rc�������w��r�˲��м������ɩ��ϸ���~q���~�Ǩ���xk���z�������~����������xj���w����������zm���������˲����u���y��|o��wi�Ȭ���������������|o��xj���x��zm�п��������������������v��~q������VC���u��xj��`O�á���vh���������������������������������˳��Ͼ��Ǫ����t���w�������~�����Ŧ������������������������������ɮ��ʲ��ѿ���_N��qb������cR���w�ž��������������������������ƨ����v������pa��ÿ�Ͷ���tf�Ÿ���tf�κ������������������������������ʰ��ǩ������������������â��ͷ���������������������������������������������������������������������������������� -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | project.xcworkspace 24 | 25 | # Android/IntelliJ 26 | # 27 | build/ 28 | .idea 29 | .gradle 30 | local.properties 31 | *.iml 32 | 33 | # node.js 34 | # 35 | node_modules/ 36 | npm-debug.log 37 | yarn-error.log 38 | 39 | # BUCK 40 | buck-out/ 41 | \.buckd/ 42 | *.keystore 43 | 44 | # fastlane 45 | # 46 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 47 | # screenshots whenever they are needed. 48 | # For more information about the recommended setup visit: 49 | # https://docs.fastlane.tools/best-practices/source-control/ 50 | 51 | */fastlane/report.xml 52 | */fastlane/Preview.html 53 | */fastlane/screenshots 54 | 55 | 56 | # Storybook 57 | # 58 | storybook-static/ 59 | storybook-static/* 60 | 61 | # Electron-Builder distributables 62 | # 63 | dist/ 64 | dist/* -------------------------------------------------------------------------------- /License: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright © 2017 SkyzohKey 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the “Software”), to deal in 7 | the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is furnished 10 | to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 19 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 20 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 | DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 12 | 13 | 19 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /.storybook/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | 3 | module.exports = (storybookBaseConfig, configType) => { 4 | storybookBaseConfig.module = { 5 | ...storybookBaseConfig.module, 6 | rules: [ 7 | ...storybookBaseConfig.module.rules, 8 | { 9 | test: /\.(jpe?g|png|gif|svg)$/i, 10 | loader: "file-loader" 11 | }, 12 | { 13 | test: /\.(js|jsx|mjs)$/, 14 | include: [ 15 | /src\/*/, 16 | /node_modules\/react-native-/, 17 | /node_modules\/react-router*/ 18 | ], 19 | loader: require.resolve("babel-loader"), 20 | options: { 21 | babelrc: false, 22 | presets: [require.resolve("babel-preset-react-native")], 23 | // ,'babel-preset-stage-0' 'babel-preset-es2015' @remove-on-eject-end This is a 24 | // feature of `babel-loader` for webpack (not Babel itself). It enables caching 25 | // results in ./node_modules/.cache/babel-loader/ directory for faster rebuilds. 26 | cacheDirectory: false 27 | } 28 | } 29 | ] 30 | }; 31 | 32 | storybookBaseConfig.resolve = { 33 | modules: ["node_modules"], 34 | extensions: [".web.js", ".js", ".json", ".web.jsx", ".jsx"], 35 | alias: { 36 | "react-native": "react-native-web" 37 | } 38 | }; 39 | 40 | return storybookBaseConfig; 41 | }; 42 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/toxclient/MainApplication.java: -------------------------------------------------------------------------------- 1 | package com.toxclient; 2 | 3 | import android.app.Application; 4 | 5 | import com.facebook.react.ReactApplication; 6 | import com.oblador.vectoricons.VectorIconsPackage; 7 | import com.facebook.react.ReactNativeHost; 8 | import com.facebook.react.ReactPackage; 9 | import com.facebook.react.shell.MainReactPackage; 10 | import com.facebook.soloader.SoLoader; 11 | 12 | import java.util.Arrays; 13 | import java.util.List; 14 | 15 | public class MainApplication extends Application implements ReactApplication { 16 | 17 | private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { 18 | @Override 19 | public boolean getUseDeveloperSupport() { 20 | return BuildConfig.DEBUG; 21 | } 22 | 23 | @Override 24 | protected List getPackages() { 25 | return Arrays.asList( 26 | new MainReactPackage(), 27 | new VectorIconsPackage() 28 | ); 29 | } 30 | 31 | @Override 32 | protected String getJSMainModuleName() { 33 | return "index"; 34 | } 35 | }; 36 | 37 | @Override 38 | public ReactNativeHost getReactNativeHost() { 39 | return mReactNativeHost; 40 | } 41 | 42 | @Override 43 | public void onCreate() { 44 | super.onCreate(); 45 | SoLoader.init(this, /* native exopackage */ false); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/components/UserButton.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import { View, Platform } from "react-native"; 3 | import { Avatar, Touchable } from "@toxclient/shathui"; 4 | 5 | const DEFAULT_SIZE = 36; 6 | const DEFAULT_PRESS_DELAY = 300; 7 | 8 | export class UserButton extends Component { 9 | render() { 10 | const { avatarUri, username, onPress } = this.props; 11 | 12 | return ( 13 | 14 | setTimeout(onPress, DEFAULT_PRESS_DELAY)} 17 | > 18 | 23 | 24 | 25 | ); 26 | } 27 | } 28 | 29 | export default UserButton; 30 | 31 | const styles = { 32 | noSelect: { 33 | ...Platform.select({ 34 | web: { 35 | userSelect: "none" 36 | } 37 | }) 38 | }, 39 | container: { 40 | width: DEFAULT_SIZE, 41 | height: DEFAULT_SIZE, 42 | borderRadius: DEFAULT_SIZE, 43 | overflow: "hidden", 44 | ...Platform.select({ 45 | web: { 46 | cursor: "pointer" 47 | }, 48 | default: { 49 | elevation: 2 50 | } 51 | }) 52 | }, 53 | ripple: { 54 | width: DEFAULT_SIZE, 55 | height: DEFAULT_SIZE, 56 | borderRadius: DEFAULT_SIZE 57 | } 58 | }; 59 | -------------------------------------------------------------------------------- /ios/toxclient/AppDelegate.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import "AppDelegate.h" 11 | 12 | #import 13 | #import 14 | 15 | @implementation AppDelegate 16 | 17 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 18 | { 19 | NSURL *jsCodeLocation; 20 | 21 | jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; 22 | 23 | RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation 24 | moduleName:@"toxclient" 25 | initialProperties:nil 26 | launchOptions:launchOptions]; 27 | rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; 28 | 29 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 30 | UIViewController *rootViewController = [UIViewController new]; 31 | rootViewController.view = rootView; 32 | self.window.rootViewController = rootViewController; 33 | [self.window makeKeyAndVisible]; 34 | return YES; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /src/components/AndroidContextMenu.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | View, 4 | UIManager, 5 | findNodeHandle, 6 | TouchableNativeFeedback 7 | } from "react-native"; 8 | import Icon from "react-native-vector-icons/MaterialIcons"; 9 | 10 | const ICON_SIZE = 24; 11 | 12 | export class AndroidContextMenu extends React.Component { 13 | constructor(props) { 14 | super(props); 15 | 16 | this.state = { 17 | icon: null 18 | }; 19 | 20 | this.onPress = this.onPress.bind(this); 21 | this.onRef = this.onRef.bind(this); 22 | } 23 | 24 | onError() { 25 | console.log("Popup Error"); 26 | } 27 | 28 | onPress = () => { 29 | console.log("icon ", this.state.icon); 30 | if (this.state.icon) { 31 | UIManager.showPopupMenu( 32 | findNodeHandle(this.state.icon), 33 | this.props.actions, 34 | this.onError, 35 | this.props.onPress 36 | ); 37 | } 38 | }; 39 | 40 | render() { 41 | return ( 42 | 43 | 44 | 50 | 51 | 52 | ); 53 | } 54 | 55 | onRef(icon) { 56 | //calback with icon component as reference 57 | console.log(icon); 58 | if (!this.state.icon) { 59 | this.setState({ icon }); 60 | } 61 | } 62 | } 63 | 64 | export default AndroidContextMenu; 65 | -------------------------------------------------------------------------------- /src/components/WelcomePlaceholder.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import { View, Text, Image } from "react-native"; 3 | 4 | import { noSelect } from "./../utilities"; 5 | import Colors from "./../styles/colors"; 6 | const TOX_ILLUSTRATION = require("./../assets/tox-illustration.png"); 7 | 8 | export class WelcomePlaceholder extends Component { 9 | render() { 10 | const { t } = this.props; 11 | return ( 12 | 13 | 14 | {t("chat:headers.welcome_back")} 15 | 16 | {t("chat:headers.info_text").toUpperCase()} 17 | 18 | 19 | ); 20 | } 21 | } 22 | 23 | export default WelcomePlaceholder; 24 | 25 | const styles = { 26 | emptyContainer: { 27 | flex: 1, 28 | height: "100%", 29 | width: "100%", 30 | flexDirection: "column", 31 | justifyContent: "center", 32 | alignItems: "center", 33 | backgroundColor: Colors.BACKGROUND, 34 | zIndex: 9000 35 | }, 36 | illustration: { 37 | height: 200, 38 | width: "60%", 39 | resizeMode: "contain", 40 | ...noSelect 41 | }, 42 | tagline: { 43 | fontSize: 30, 44 | fontWeight: "lighter", 45 | color: Colors.PRIMARY_TEXT, 46 | padding: 12, 47 | ...noSelect 48 | }, 49 | infoText: { 50 | fontSize: 14, 51 | fontWeight: "bold", 52 | color: Colors.SECONDARY_TEXT, 53 | padding: 4, 54 | width: "60%", 55 | textAlign: "center", 56 | lineHeight: 24, 57 | ...noSelect 58 | } 59 | }; 60 | -------------------------------------------------------------------------------- /.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | ; We fork some components by platform 3 | .*/*[.]android.js 4 | 5 | ; Ignore "BUCK" generated dirs 6 | /\.buckd/ 7 | 8 | ; Ignore unexpected extra "@providesModule" 9 | .*/node_modules/.*/node_modules/fbjs/.* 10 | 11 | ; Ignore duplicate module providers 12 | ; For RN Apps installed via npm, "Libraries" folder is inside 13 | ; "node_modules/react-native" but in the source repo it is in the root 14 | .*/Libraries/react-native/React.js 15 | 16 | ; Ignore polyfills 17 | .*/Libraries/polyfills/.* 18 | 19 | ; Ignore metro 20 | .*/node_modules/metro/.* 21 | 22 | [include] 23 | 24 | [libs] 25 | node_modules/react-native/Libraries/react-native/react-native-interface.js 26 | node_modules/react-native/flow/ 27 | node_modules/react-native/flow-github/ 28 | 29 | [options] 30 | emoji=true 31 | 32 | module.system=haste 33 | 34 | munge_underscores=true 35 | 36 | module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub' 37 | 38 | module.file_ext=.js 39 | module.file_ext=.jsx 40 | module.file_ext=.json 41 | module.file_ext=.native.js 42 | 43 | suppress_type=$FlowIssue 44 | suppress_type=$FlowFixMe 45 | suppress_type=$FlowFixMeProps 46 | suppress_type=$FlowFixMeState 47 | 48 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) 49 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+ 50 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy 51 | suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError 52 | 53 | [version] 54 | ^0.63.0 55 | -------------------------------------------------------------------------------- /src/i18n/i18n.js: -------------------------------------------------------------------------------- 1 | import i18n from "i18next"; 2 | import { Platform } from "react-native"; 3 | import { reactI18nextModule } from "react-i18next"; 4 | 5 | // Language Folders 6 | import en from "./en/index"; 7 | import fr from "./fr/index"; 8 | import tr from "./tr/index"; 9 | 10 | /** 11 | * @todo Android/iOS/WindowsPhone language detection 12 | * @body Need to find a way to detect language on mobile devices to make the translation system working everywhere. 13 | */ 14 | let defaultLanguage = "en"; 15 | if (Platform.OS === "web") { 16 | // Won't work on the real web. 17 | defaultLanguage = navigator.language.substr(0, 2); 18 | } else if (Platform.OS === "android") { 19 | const { NativeModules } = require("react-native"); 20 | defaultLanguage = NativeModules.I18nManager.localeIdentifier.substr(0, 2); 21 | } else if (Platform.OS === "ios") { 22 | const { NativeModules } = require("react-native"); 23 | defaultLanguage = NativeModules.SettingsManager.settings.AppleLocale.substr( 24 | 0, 25 | 2 26 | ); 27 | } 28 | 29 | const isDev = require("electron-is-dev"); 30 | const moment = require("moment"); 31 | 32 | i18n.use(reactI18nextModule).init({ 33 | lng: defaultLanguage, 34 | fallbackLng: "en", 35 | debug: isDev, 36 | defaultNS: "login", 37 | resources: { 38 | en, 39 | fr, 40 | tr 41 | }, 42 | interpolation: { 43 | function(value, format, lng) { 44 | if (value instanceof Date) return moment(value).format(format); 45 | return value; 46 | } 47 | }, 48 | react: { 49 | wait: false, 50 | bindI18n: false, 51 | bindStore: false, 52 | nsMode: false 53 | } 54 | }); 55 | 56 | i18n.on("languageChanged", currentLang => { 57 | moment.locale(currentLang); 58 | }); 59 | 60 | moment.locale(defaultLanguage); 61 | 62 | export default i18n; 63 | -------------------------------------------------------------------------------- /ios/toxclient-tvOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UIViewControllerBasedStatusBarAppearance 38 | 39 | NSLocationWhenInUseUsageDescription 40 | 41 | NSAppTransportSecurity 42 | 43 | 44 | NSExceptionDomains 45 | 46 | localhost 47 | 48 | NSExceptionAllowsInsecureHTTPLoads 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /android/app/BUCK: -------------------------------------------------------------------------------- 1 | # To learn about Buck see [Docs](https://buckbuild.com/). 2 | # To run your application with Buck: 3 | # - install Buck 4 | # - `npm start` - to start the packager 5 | # - `cd android` 6 | # - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"` 7 | # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck 8 | # - `buck install -r android/app` - compile, install and run application 9 | # 10 | 11 | lib_deps = [] 12 | 13 | for jarfile in glob(['libs/*.jar']): 14 | name = 'jars__' + jarfile[jarfile.rindex('/') + 1: jarfile.rindex('.jar')] 15 | lib_deps.append(':' + name) 16 | prebuilt_jar( 17 | name = name, 18 | binary_jar = jarfile, 19 | ) 20 | 21 | for aarfile in glob(['libs/*.aar']): 22 | name = 'aars__' + aarfile[aarfile.rindex('/') + 1: aarfile.rindex('.aar')] 23 | lib_deps.append(':' + name) 24 | android_prebuilt_aar( 25 | name = name, 26 | aar = aarfile, 27 | ) 28 | 29 | android_library( 30 | name = "all-libs", 31 | exported_deps = lib_deps, 32 | ) 33 | 34 | android_library( 35 | name = "app-code", 36 | srcs = glob([ 37 | "src/main/java/**/*.java", 38 | ]), 39 | deps = [ 40 | ":all-libs", 41 | ":build_config", 42 | ":res", 43 | ], 44 | ) 45 | 46 | android_build_config( 47 | name = "build_config", 48 | package = "com.toxclient", 49 | ) 50 | 51 | android_resource( 52 | name = "res", 53 | package = "com.toxclient", 54 | res = "src/main/res", 55 | ) 56 | 57 | android_binary( 58 | name = "app", 59 | keystore = "//android/keystores:debug", 60 | manifest = "src/main/AndroidManifest.xml", 61 | package_type = "debug", 62 | deps = [ 63 | ":app-code", 64 | ], 65 | ) 66 | -------------------------------------------------------------------------------- /App.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is used by the native apps. 3 | */ 4 | 5 | import React from "react"; 6 | import { View, StatusBar } from "react-native"; 7 | import { Provider as StoreProvider } from "react-redux"; 8 | import { I18nextProvider } from "react-i18next"; 9 | import i18n from "./src/i18n/i18n"; 10 | 11 | import Routing, { Router, Switch } from "./src/utilities/routing/index"; 12 | import { BackButton } from "./src/utilities/routing/router"; 13 | import store from "./src/utilities/storage/store"; 14 | import Colors from "./src/styles/colors"; 15 | 16 | import LoginScreen from "./src/containers/LoginScreenContainer"; 17 | import RegisterScreen from "./src/containers/RegisterScreenContainer"; 18 | import RecentsScreen from "./src/containers/RecentsScreenContainer"; 19 | import ChatScreen from "./src/containers/ChatScreenContainer"; 20 | 21 | const Route = Routing.Route; 22 | 23 | class App extends React.Component { 24 | render() { 25 | const App = (props, context) => ( 26 | 27 | 32 | {props.children} 33 | 34 | ); 35 | 36 | return ( 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | ); 53 | } 54 | } 55 | 56 | export default App; 57 | -------------------------------------------------------------------------------- /src/utilities/MockData/ContactsMock.js: -------------------------------------------------------------------------------- 1 | import Presence from "../enums/Presence"; 2 | 3 | export const getContactsMock = () => { 4 | return [ 5 | { 6 | pubkey: 7 | "3GE0HU76J6KHHNMBKPYD3S7LOJ5PFLFPIIEHFXDKV0KFQCPRZP2HDTGNLS9ZAF26", 8 | username: "Ogromny | FNC", 9 | status: "Vive les vaches normandes! 🤠 🐮", 10 | presence: Presence.ONLINE, 11 | avatarUri: "https://avatars.githubusercontent.com/Ogromny?size=46", 12 | lastMessageTimestamp: 1519659888, 13 | unread: true 14 | }, 15 | { 16 | pubkey: 17 | "14DDWYA1XW454N564PQ1LV5JJD44NWFJWCPUEDFG9FV6MB0FKTFCFVEDADKO5HXS", 18 | username: "Sean Perkins", 19 | status: 20 | "I think this idea could work, I just need to put more energy into it.", 21 | presence: Presence.BUSY, 22 | avatarUri: "https://personagenerator.com/user-sean.png", 23 | lastMessageTimestamp: 1519647578, 24 | unread: false 25 | }, 26 | { 27 | pubkey: 28 | "IWJK4K5VZZ70E9X1DA724PFX3THR6N7GTHN4UKXZAVLKPNRJTEARS649QQ6M8JC3", 29 | username: "Joan Perez", 30 | status: "My students come first in everything I do. 🙂", 31 | presence: Presence.AWAY, 32 | avatarUri: "https://personagenerator.com/user-7.png", 33 | lastMessageTimestamp: 1519647032, 34 | unread: false 35 | }, 36 | { 37 | pubkey: 38 | "NOYGLAIMCQL5IJKQIGPEOBJI7APNJC1BIZFR6VK2JSFZRV01NNMYZSVULTKXUNIW", 39 | username: "Ricky Metzger", 40 | status: 41 | "I love this idea, and I can't wait to test it with our customers!", 42 | presence: Presence.OFFLINE, 43 | avatarUri: "https://personagenerator.com/user-ricky.png", 44 | lastMessageTimestamp: 1519642102, 45 | unread: false 46 | }, 47 | { 48 | pubkey: 49 | "NOYGLAIMCQL5IX1DA724PFX3THR6N7GTHN4UKXZAVLKJKQIGPEOBJI7APNJC1BIZ", 50 | username: "John Doe", 51 | status: "Yeah.", 52 | presence: Presence.OFFLINE, 53 | lastMessageTimestamp: 1519642062, 54 | unread: false 55 | } 56 | ]; 57 | }; 58 | -------------------------------------------------------------------------------- /config/paths.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const fs = require('fs'); 5 | const url = require('url'); 6 | 7 | // Make sure any symlinks in the project folder are resolved: 8 | // https://github.com/facebookincubator/create-react-app/issues/637 9 | const appDirectory = fs.realpathSync(process.cwd()); 10 | const resolveApp = relativePath => path.resolve(appDirectory, relativePath); 11 | 12 | const envPublicUrl = process.env.PUBLIC_URL; 13 | 14 | function ensureSlash(path, needsSlash) { 15 | const hasSlash = path.endsWith('/'); 16 | if (hasSlash && !needsSlash) { 17 | return path.substr(path, path.length - 1); 18 | } else if (!hasSlash && needsSlash) { 19 | return `${path}/`; 20 | } else { 21 | return path; 22 | } 23 | } 24 | 25 | const getPublicUrl = appPackageJson => 26 | envPublicUrl || require(appPackageJson).homepage; 27 | 28 | // We use `PUBLIC_URL` environment variable or "homepage" field to infer 29 | // "public path" at which the app is served. 30 | // Webpack needs to know it to put the right