diff --git a/.babelrc b/.babelrc index 4b5e8ad..36fecf6 100644 --- a/.babelrc +++ b/.babelrc @@ -1,3 +1,3 @@ { - "presets": ["module:metro-react-native-babel-preset", "react-app"] + "presets": ["module:metro-react-native-babel-preset", "react-app", "@babel/preset-typescript"] } diff --git a/.gitignore b/.gitignore index 712e532..77856fe 100644 --- a/.gitignore +++ b/.gitignore @@ -67,4 +67,4 @@ public/favicon* **/.#* # TernJS -*/.tern-port \ No newline at end of file +*/.tern-port diff --git a/android/app/build.gradle b/android/app/build.gradle index b4cc1f7..42edbfc 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -73,7 +73,7 @@ import com.android.build.OutputFile */ project.ext.react = [ - entryFile: "index.js" + entryFile: "index.ts" ] apply from: "../../node_modules/react-native/react.gradle" diff --git a/package.json b/package.json index 07a388c..2d66ad0 100644 --- a/package.json +++ b/package.json @@ -1,174 +1,178 @@ { - "name": "jellyfinclient", - "productName": "Jellyfin Client", - "version": "0.0.1", - "private": true, - "scripts": { - "start": "node node_modules/react-native/local-cli/cli.js start", - "test": "jest", - "android": "react-native run-android", - "android:clean": "cd android && ./gradlew clean", - "android:dev_menu": "adb shell input keyevent KEYCODE_MENU", - "android:emulator": "scripts/android_emulator.js", - "android:kill_server": "scripts/kill_server.sh", - "android:log": "react-native log-android", - "android:release": "cd android && ./gradlew assembleRelease", - "electron": "electron build", - "electron:release": "electron-packager build --all --asar --icon=public/app --overwrite --out=electron", - "icon-gen": "icon-gen -i resources/icon.svg -o public && shx cp public/favicon-228.png public/app.png", - "install": "node scripts/install.js", - "ios": "react-native run-ios", - "ios:release": "react-native bundle --platform=ios", - "preandroid": "scripts/preandroid.sh", - "preelectron": "cross-env-shell ELECTRON=1 PUBLIC_URL=. \"yarn run web:release && shx cp index.electron.js build/index.js && echo {} > build/package.json\"", - "preelectron:release": "yarn run preelectron", - "preweb:release": "yarn run icon-gen", - "release": "yarn run android:release && yarn run electron:release && yarn run ios:release && yarn run web:release && yarn run windows:release", - "test:web": "node scripts/test.js --env=jsdom", - "web": "node scripts/start.js", - "web:release": "node scripts/build.js", - "windows": "react-native run-windows", - "windows:release": "react-native bundle --platform=windows --entry-file index.js --assets-dest windows/jellyfinclient/ReactAssets --bundle-output windows/jellyfinclient/ReactAssets/index.windows.bundle --dev false" - }, - "dependencies": { - "electron-store": "^2.0.0", - "electron-store-webpack-wrapper": "^0.0.2", - "formik": "^1.4.2", - "fs-extra": "7.0.0", - "is-electron": "^2.2.0", - "jellyfin-apiclient": "^1.0.0", - "prop-types": "^15.6.2", - "react": "16.6.3", - "react-app-polyfill": "^0.1.3", - "react-art": "16.7.0", - "react-dev-utils": "^6.1.1", - "react-dom": "16.7.0", - "react-native": "0.59.9", - "react-native-sensitive-info": "^5.2.7", - "react-native-web_improved": "0.9.9", - "react-native-windows": "0.57.0-rc.4", - "react-redux": "^6.0.0", - "react-router": "^4.3.1", - "react-router-dom": "^4.3.1", - "react-router-native": "^4.3.0", - "react-router-navigation": "^2.0.0-alpha.10", - "redux": "^4.0.1", - "redux-persist": "^5.10.0", - "redux-persist-electron-storage": "^2.0.0", - "redux-persist-sensitive-storage": "^1.0.0", - "redux-thunk": "^2.3.0", - "resolve": "1.8.1" - }, - "devDependencies": { - "@babel/core": "^7.2.2", - "@svgr/webpack": "2.4.1", - "@types/jest": "^23.3.13", - "@types/react": "^16.7.20", - "@types/react-native": "^0.57.29", - "@types/react-redux": "^7.0.0", - "babel-core": "7.0.0-bridge.0", - "babel-eslint": "9.0.0", - "babel-jest": "23.6.0", - "babel-loader": "8.0.4", - "babel-plugin-named-asset-import": "^0.2.3", - "babel-plugin-react-native-web": "0.9.9", - "babel-plugin-transform-react-remove-prop-types": "0.4.21", - "babel-preset-react-app": "^6.1.0", - "bfj": "6.1.1", - "case-sensitive-paths-webpack-plugin": "2.1.2", - "chalk": "2.4.1", - "cross-env": "^5.2.0", - "css-loader": "1.0.0", - "dotenv": "6.0.0", - "dotenv-expand": "4.2.0", - "electron": "^4.0.1", - "electron-packager": "^13.0.1", - "eslint": "5.6.0", - "eslint-config-react-app": "^3.0.5", - "eslint-loader": "2.1.1", - "eslint-plugin-flowtype": "2.50.1", - "eslint-plugin-import": "2.14.0", - "eslint-plugin-jsx-a11y": "6.1.2", - "eslint-plugin-react": "7.11.1", - "file-loader": "2.0.0", - "fork-ts-checker-webpack-plugin-alt": "0.4.14", - "html-webpack-plugin": "4.0.0-alpha.2", - "icon-gen": "2.0.0", - "identity-obj-proxy": "3.0.0", - "jest": "23.6.0", - "jest-pnp-resolver": "1.0.1", - "jest-resolve": "23.6.0", - "metro-react-native-babel-preset": "0.51.1", - "mini-css-extract-plugin": "0.4.3", - "optimize-css-assets-webpack-plugin": "5.0.1", - "pnp-webpack-plugin": "1.1.0", - "postcss-flexbugs-fixes": "4.1.0", - "postcss-loader": "3.0.0", - "postcss-preset-env": "6.0.6", - "postcss-safe-parser": "4.0.1", - "prettier": "^1.18.2", - "react-test-renderer": "16.6.3", - "rnpm-plugin-windows": "0.2.8", - "sass-loader": "7.1.0", - "shx": "^0.3.2", - "style-loader": "0.23.0", - "terser-webpack-plugin": "1.1.0", - "typescript": "^3.2.4", - "url-loader": "1.1.1", - "webpack": "4.19.1", - "webpack-dev-server": "3.1.14", - "webpack-manifest-plugin": "2.0.4", - "workbox-webpack-plugin": "3.6.3" - }, - "jest": { - "preset": "react-native", - "collectCoverageFrom": [ - "src/**/*.{js,jsx,ts,tsx}", - "!src/**/*.d.ts" - ], - "resolver": "jest-pnp-resolver", - "setupFiles": [ - "react-app-polyfill/jsdom" - ], - "testMatch": [ - "/src/**/__tests__/**/*.{js,jsx,ts,tsx}", - "/src/**/?(*.)(spec|test).{js,jsx,ts,tsx}" - ], - "testEnvironment": "jsdom", - "testURL": "http://localhost", - "transform": { - "^.+\\.(js|jsx|ts|tsx)$": "/node_modules/babel-jest", - "^.+\\.css$": "/config/jest/cssTransform.js", - "^(?!.*\\.(js|jsx|ts|tsx|css|json)$)": "/config/jest/fileTransform.js" + "name": "jellyfinclient", + "productName": "Jellyfin Client", + "version": "0.0.1", + "private": true, + "scripts": { + "start": "node node_modules/react-native/local-cli/cli.js start", + "test": "jest", + "android": "react-native run-android", + "android:clean": "cd android && ./gradlew clean", + "android:dev_menu": "adb shell input keyevent KEYCODE_MENU", + "android:emulator": "scripts/android_emulator.js", + "android:kill_server": "scripts/kill_server.sh", + "android:log": "react-native log-android", + "android:release": "cd android && ./gradlew assembleRelease", + "electron": "electron build", + "electron:release": "electron-packager build --all --asar --icon=public/app --overwrite --out=electron", + "icon-gen": "icon-gen -i resources/icon.svg -o public && shx cp public/favicon-228.png public/app.png", + "install": "node scripts/install.js", + "ios": "react-native run-ios", + "ios:release": "react-native bundle --platform=ios", + "preandroid": "scripts/preandroid.sh", + "preelectron": "cross-env-shell ELECTRON=1 PUBLIC_URL=. \"yarn run web:release && shx cp index.electron.js build/index.js && echo {} > build/package.json\"", + "preelectron:release": "yarn run preelectron", + "preweb:release": "yarn run icon-gen", + "release": "yarn run android:release && yarn run electron:release && yarn run ios:release && yarn run web:release && yarn run windows:release", + "test:web": "node scripts/test.js --env=jsdom", + "web": "node scripts/start.js", + "web:release": "node scripts/build.js", + "windows": "react-native run-windows", + "windows:release": "react-native bundle --platform=windows --entry-file index.js --assets-dest windows/jellyfinclient/ReactAssets --bundle-output windows/jellyfinclient/ReactAssets/index.windows.bundle --dev false" }, - "transformIgnorePatterns": [ - "[/\\\\]node_modules[/\\\\].+\\.(js|jsx|ts|tsx)$", - "^.+\\.module\\.(css|sass|scss)$" - ], - "moduleNameMapper": { - "^react-native$": "react-native-web", - "^.+\\.module\\.(css|sass|scss)$": "identity-obj-proxy" + "dependencies": { + "electron-store": "^2.0.0", + "electron-store-webpack-wrapper": "^0.0.2", + "formik": "^1.4.2", + "fs-extra": "7.0.0", + "is-electron": "^2.2.0", + "jellyfin-apiclient": "^1.0.0", + "prop-types": "^15.6.2", + "react": "16.6.3", + "react-app-polyfill": "^0.1.3", + "react-art": "16.7.0", + "react-dev-utils": "^6.1.1", + "react-dom": "16.7.0", + "react-native": "0.59.9", + "react-native-sensitive-info": "^5.2.7", + "react-native-web_improved": "0.9.9", + "react-native-windows": "0.57.0-rc.4", + "react-redux": "^6.0.0", + "react-router": "^4.3.1", + "react-router-dom": "^4.3.1", + "react-router-native": "^4.3.0", + "react-router-navigation": "^2.0.0-alpha.10", + "redux": "^4.0.1", + "redux-persist": "^5.10.0", + "redux-persist-electron-storage": "^2.0.0", + "redux-persist-sensitive-storage": "^1.0.0", + "redux-thunk": "^2.3.0", + "resolve": "1.8.1" }, - "moduleFileExtensions": [ - "web.js", - "js", - "web.ts", - "ts", - "web.tsx", - "tsx", - "json", - "web.jsx", - "jsx", - "node" - ] - }, - "browserslist": [ - ">0.2%", - "not dead", - "not ie <= 11", - "not op_mini all" - ], - "eslintConfig": { - "extends": "react-app" - } + "devDependencies": { + "core-js": "3", + "@babel/core": "^7.2.2", + "@babel/preset-typescript": "^7.6.0", + "@svgr/webpack": "2.4.1", + "@types/jest": "^23.3.13", + "@types/react": "^16.7.20", + "@types/react-native": "^0.57.29", + "@types/react-redux": "^7.0.0", + "@types/react-router": "^5.1.1", + "@types/react-router-dom": "^5.1.0", + "babel-core": "7.0.0-bridge.0", + "babel-eslint": "9.0.0", + "babel-jest": "23.6.0", + "babel-loader": "8.0.4", + "babel-plugin-named-asset-import": "^0.2.3", + "babel-plugin-react-native-web": "0.9.9", + "babel-plugin-transform-react-remove-prop-types": "0.4.21", + "babel-preset-react-app": "^6.1.0", + "bfj": "6.1.1", + "case-sensitive-paths-webpack-plugin": "2.1.2", + "chalk": "2.4.1", + "cross-env": "^5.2.0", + "css-loader": "1.0.0", + "dotenv": "6.0.0", + "dotenv-expand": "4.2.0", + "electron": "^4.0.1", + "electron-packager": "^13.0.1", + "eslint": "5.6.0", + "eslint-config-react-app": "^3.0.5", + "eslint-loader": "2.1.1", + "eslint-plugin-flowtype": "2.50.1", + "eslint-plugin-import": "2.14.0", + "eslint-plugin-jsx-a11y": "6.1.2", + "eslint-plugin-react": "7.11.1", + "file-loader": "2.0.0", + "fork-ts-checker-webpack-plugin-alt": "0.4.14", + "html-webpack-plugin": "4.0.0-alpha.2", + "icon-gen": "2.0.0", + "identity-obj-proxy": "3.0.0", + "jest": "23.6.0", + "jest-pnp-resolver": "1.0.1", + "jest-resolve": "23.6.0", + "metro-react-native-babel-preset": "0.51.1", + "mini-css-extract-plugin": "0.4.3", + "optimize-css-assets-webpack-plugin": "5.0.1", + "pnp-webpack-plugin": "1.1.0", + "postcss-flexbugs-fixes": "4.1.0", + "postcss-loader": "3.0.0", + "postcss-preset-env": "6.0.6", + "postcss-safe-parser": "4.0.1", + "react-native-typescript-transformer": "^1.2.13", + "react-test-renderer": "16.6.3", + "rnpm-plugin-windows": "0.2.8", + "sass-loader": "7.1.0", + "shx": "^0.3.2", + "style-loader": "0.23.0", + "terser-webpack-plugin": "1.1.0", + "typescript": "^3.6.3", + "url-loader": "1.1.1", + "webpack": "4.19.1", + "webpack-dev-server": "3.1.14", + "webpack-manifest-plugin": "2.0.4", + "workbox-webpack-plugin": "3.6.3" + }, + "jest": { + "preset": "react-native", + "collectCoverageFrom": [ + "src/**/*.{js,jsx,ts,tsx}", + "!src/**/*.d.ts" + ], + "resolver": "jest-pnp-resolver", + "setupFiles": [ + "react-app-polyfill/jsdom" + ], + "testMatch": [ + "/src/**/__tests__/**/*.{js,jsx,ts,tsx}", + "/src/**/?(*.)(spec|test).{js,jsx,ts,tsx}" + ], + "testEnvironment": "jsdom", + "testURL": "http://localhost", + "transform": { + "^.+\\.(js|jsx|ts|tsx)$": "/node_modules/babel-jest", + "^.+\\.css$": "/config/jest/cssTransform.js", + "^(?!.*\\.(js|jsx|ts|tsx|css|json)$)": "/config/jest/fileTransform.js" + }, + "transformIgnorePatterns": [ + "[/\\\\]node_modules[/\\\\].+\\.(js|jsx|ts|tsx)$", + "^.+\\.module\\.(css|sass|scss)$" + ], + "moduleNameMapper": { + "^react-native$": "react-native-web", + "^.+\\.module\\.(css|sass|scss)$": "identity-obj-proxy" + }, + "moduleFileExtensions": [ + "web.js", + "js", + "web.ts", + "ts", + "web.tsx", + "tsx", + "json", + "web.jsx", + "jsx", + "node" + ] + }, + "browserslist": [ + ">0.2%", + "not dead", + "not ie <= 11", + "not op_mini all" + ], + "eslintConfig": { + "extends": "react-app" + } } diff --git a/src/App.js b/src/App.tsx similarity index 95% rename from src/App.js rename to src/App.tsx index bd478c5..2d1d168 100644 --- a/src/App.js +++ b/src/App.tsx @@ -5,7 +5,7 @@ import EntryScreen from "./screens/EntryScreen"; import NoMatch from "./components/NoMatch"; import ElectronRedirect from "./components/ElectronRedirect"; import jellyfinStore from "./utilities/storage/store"; -import { Router, Switch, Route } from "./utilities/routing/index"; +import { Router, Switch, Route } from "./utilities/routing"; import { PersistGate } from "redux-persist/integration/react"; import Loading from "./components/Loading"; import HomeComponent from "./components/HomeComponent"; diff --git a/src/Props.ts b/src/Props.ts new file mode 100644 index 0000000..83dd40f --- /dev/null +++ b/src/Props.ts @@ -0,0 +1,36 @@ +// Contains the definition for the props used in Jellyfin +import { ActionType } from "./actions/ActionType"; +import { AnyAction, Dispatch } from "redux"; + +export interface JellyfinAction { + type: ActionType, + username: string, + userId: string, + token: string, + loginStatus: boolean, + address: string, + port: string, + apiClient: any +} + +export interface Storage { + jellyfinInterface: { + apiClient: any + }, + authCredentials: { + userId: string, + username: string + } +} +export interface ConnectionStatus { + serverAddress: string, + serverPort: string, + connectStatus: boolean +} + +export interface JellyfinProps { + connectionStatus: ConnectionStatus, + connectAction: (state: any) => void, + storage: Storage, + dispatch: (dispatch: Dispatch) => void, +} diff --git a/src/actions/ActionType.ts b/src/actions/ActionType.ts new file mode 100644 index 0000000..39b0c49 --- /dev/null +++ b/src/actions/ActionType.ts @@ -0,0 +1,11 @@ +// This file serves as a common location for all your action constants + +export enum ActionType { + CONNECT_SUCCESSFUL = "CONNECT_SUCCESSFUL", + CONNECT_FAILED = "CONNECT_FAILED", + LOGIN_SUCCESSFUL = "LOGIN_SUCCESSFUL", + LOGIN_FAILED = "LOGIN_FAILED", + SOMETHING_HAPPENED_SUCCESSFULLY = "SOMETHING_HAPPENED_SUCCESSFULLY", + SOMETHING_FAILED = "SOMETHING_FAILED", + UPDATE_APICLIENT = "UPDATE_APICLIENT", +} diff --git a/src/actions/ActionTypes.js b/src/actions/ActionTypes.js deleted file mode 100644 index d579db9..0000000 --- a/src/actions/ActionTypes.js +++ /dev/null @@ -1,9 +0,0 @@ -// This file serves as a common location for all your action constants - -export const CONNECT_SUCCESSFUL = "CONNECT_SUCCESSFUL"; -export const CONNECT_FAILED = "CONNECT_FAILED"; -export const LOGIN_SUCCESSFUL = "LOGIN_SUCCESSFUL"; -export const LOGIN_FAILED = "LOGIN_FAILED"; -export const SOMETHING_HAPPENED_SUCCESSFULLY = "SOMETHING_HAPPENED_SUCCESSFULLY"; -export const SOMETHING_FAILED = "SOMETHING_FAILED"; -export const UPDATE_APICLIENT = "UPDATE_APICLIENT"; diff --git a/src/actions/ApiFunctions.js b/src/actions/ApiFunctions.js deleted file mode 100644 index 156fa3e..0000000 --- a/src/actions/ApiFunctions.js +++ /dev/null @@ -1,38 +0,0 @@ -import ApiClient from "jellyfin-apiclient/dist/apiclient"; -import jellyfinStore from "../utilities/storage/store"; -import * as types from "./ActionTypes"; - -export const connectToJellyfin = function(address) { - let apiClient = new ApiClient(null, address, "Jellyfin WebNG", "0.0.1", "WebNG", "WebNG", ""); - jellyfinStore.store.dispatch({ - type: types.UPDATE_APICLIENT, - apiClient: apiClient - }); -}; - -export const loginToJellyfin = async function(username, password) { - let apiClient = copyClientFromStore(); - let auth = await apiClient.authenticateUserByName(username, password); - jellyfinStore.store.dispatch(loginSuccessfully(auth.User.Name, auth.User.Id, auth.AccessToken)); - apiClient.setAuthenticationInfo(auth.AccessToken, auth.User.Id); - jellyfinStore.store.dispatch({ - type: types.UPDATE_APICLIENT, - apiClient: apiClient - }); -}; - -export const copyClientFromStore = function() { - let apiClient = jellyfinStore.store.getState().jellyfinInterface.apiClient; - return Object.assign(new ApiClient(null, "-", "Jellyfin WebNG", "0.0.1", "WebNG", "WebNG", ""), apiClient); -}; - -//Dispatch Action Helper: - -function loginSuccessfully(username, userid, token) { - return { - type: types.LOGIN_SUCCESSFUL, - username, - userid, - token - }; -} diff --git a/src/actions/ApiFunctions.ts b/src/actions/ApiFunctions.ts new file mode 100644 index 0000000..d1c9d5d --- /dev/null +++ b/src/actions/ApiFunctions.ts @@ -0,0 +1,37 @@ +import ApiClient from "jellyfin-apiclient/dist/apiclient"; +import jellyfinStore from "../utilities/storage/store"; +import { ActionType } from "./ActionType"; + +export const connectToJellyfin = function(address: string) { + const apiClient = new ApiClient(null, address, "Jellyfin WebNG", "0.0.1", "WebNG", "WebNG", ""); + jellyfinStore.store.dispatch({ + type: ActionType.UPDATE_APICLIENT, + apiClient: apiClient + }); +}; + +export const loginToJellyfin = async function(username: string, password: string) { + const apiClient = copyClientFromStore(); + const auth = await apiClient.authenticateUserByName(username, password); + jellyfinStore.store.dispatch(loginSuccessfully(auth.User.Name, auth.User.Id, auth.AccessToken)); + apiClient.setAuthenticationInfo(auth.AccessToken, auth.User.Id); + jellyfinStore.store.dispatch({ + type: ActionType.UPDATE_APICLIENT, + apiClient: apiClient + }); +}; + +export const copyClientFromStore = function() { + const apiClient = jellyfinStore.store.getState().jellyfinInterface.apiClient; + return Object.assign(new ApiClient(null, "-", "Jellyfin WebNG", "0.0.1", "WebNG", "WebNG", ""), apiClient); +}; + +//Dispatch Action Helper: +function loginSuccessfully(username: string, userid: string, token: string) { + return { + type: ActionType.LOGIN_SUCCESSFUL, + username, + userid, + token + }; +} diff --git a/src/actions/ConnectAction.js b/src/actions/ConnectAction.ts similarity index 52% rename from src/actions/ConnectAction.js rename to src/actions/ConnectAction.ts index a3d42ec..d81b12d 100644 --- a/src/actions/ConnectAction.js +++ b/src/actions/ConnectAction.ts @@ -1,20 +1,25 @@ -import * as types from "./ActionTypes"; import { connectToJellyfin } from "./ApiFunctions"; import jellyfinStore from "../utilities/storage/store"; +import { ActionType } from "./ActionType"; -export default function connectToServer(serverAddress, port) { - return dispatch => { +export default function connectToServer(serverAddress: string, port: string) { + return (dispatch: any) => { let plainServerAddress = serverAddress; serverAddress = normalizeAddress(serverAddress); serverAddress = serverAddress + ":" + port; connectToJellyfin(serverAddress); try { - let apiClient = jellyfinStore.store.getState().jellyfinInterface.apiClient; - apiClient.getPublicSystemInfo().then(result => { - console.log("Connected"); - console.log(result); - return dispatch(connectSuccessful(plainServerAddress, port)); - }); + //TODO No any anywhere + const apiClient: any = jellyfinStore.store.getState().jellyfinInterface.apiClient; + if(apiClient) { + apiClient.getPublicSystemInfo().then((result: any) => { + console.log("Connected"); + console.log(result); + return dispatch(connectSuccessful(plainServerAddress, port)); + }); + } else { + throw new Error("API Client is undefined"); + } } catch (err) { console.log("Unable to connect."); return dispatch(connectFailed(plainServerAddress, port)); @@ -22,12 +27,12 @@ export default function connectToServer(serverAddress, port) { }; } -function replaceAll(originalString, strReplace, strWith) { +function replaceAll(originalString: string, strReplace: string, strWith: string) { const reg = new RegExp(strReplace, "ig"); return originalString.replace(reg, strWith); } -function normalizeAddress(serverAddress) { +function normalizeAddress(serverAddress: string) { // attempt to correct bad input serverAddress = serverAddress.trim(); @@ -42,17 +47,17 @@ function normalizeAddress(serverAddress) { return serverAddress; } -function connectSuccessful(address, port) { +function connectSuccessful(address: string, port: string) { return { - type: types.CONNECT_SUCCESSFUL, + type: ActionType.CONNECT_SUCCESSFUL, address, port }; } -function connectFailed(address, port) { +function connectFailed(address: string, port: string) { return { - type: types.CONNECT_FAILED, + type: ActionType.CONNECT_FAILED, address, port }; diff --git a/src/components/ElectronRedirect.js b/src/components/ElectronRedirect.tsx similarity index 82% rename from src/components/ElectronRedirect.js rename to src/components/ElectronRedirect.tsx index f53675f..0890b12 100644 --- a/src/components/ElectronRedirect.js +++ b/src/components/ElectronRedirect.tsx @@ -1,5 +1,5 @@ import React, { Component } from "react"; -import { Redirect } from "../utilities/routing/index"; +import { Redirect } from "../utilities/routing"; //This is a component to make Electron load index.html and then forward to the correct Route. diff --git a/src/components/EntryComponent.js b/src/components/EntryComponent.tsx similarity index 61% rename from src/components/EntryComponent.js rename to src/components/EntryComponent.tsx index 6ddb191..43adede 100644 --- a/src/components/EntryComponent.js +++ b/src/components/EntryComponent.tsx @@ -1,18 +1,31 @@ -import React, { Component } from "react"; +import React, { PureComponent } from "react"; import { View, TextInput, Button, Image } from "react-native"; import styles from "./Style"; import { Formik } from "formik"; import { connect } from "react-redux"; -import { Redirect } from "../utilities/routing"; +import { Redirect } from "react-router"; +import { ConnectionStatus, JellyfinProps } from "../Props"; +import ConnectAction from "../actions/ConnectAction"; -class EntryComponent extends Component { - constructor(props, context) { - super(props, context); +export interface EntryComponentState { + server: string, + port: string, + connectButtonMessage: string, + connectionStatus: ConnectionStatus +} + +class EntryComponent extends PureComponent { + constructor(props: JellyfinProps) { + super(props); this.state = { server: "", port: "", connectButtonMessage: "Connect", - connectStatus: false + connectionStatus : { + serverAddress: "", + serverPort: "", + connectStatus: false + }, }; } @@ -24,23 +37,28 @@ class EntryComponent extends Component { } componentDidUpdate() { - if (this.state.connectStatus !== this.props.connectionStatus.connectStatus) + if (this.state.connectionStatus.connectStatus !== this.props.connectionStatus.connectStatus) this.setState({ - connectStatus: this.props.connectionStatus.connectStatus + connectionStatus: { + serverAddress: this.props.connectionStatus.serverAddress, + serverPort: this.props.connectionStatus.serverPort, + connectStatus: this.props.connectionStatus.connectStatus + } }); } render() { - return this.state.connectStatus ? ( + return this.state.connectionStatus.connectStatus ? ( ) : ( { - this.props.connectAction(this.state); + this.props.dispatch(ConnectAction(this.state.server, this.state.port)); }} - render={({ handleSubmit }) => ( + render={props => ( @@ -65,7 +83,7 @@ class EntryComponent extends Component { -