diff --git a/README.md b/README.md
index e24e6ab..f4106a8 100644
--- a/README.md
+++ b/README.md
@@ -33,6 +33,7 @@ ReactTV.render(, document.getElementById('root'))
- [About React-TV](#about-react-tv)
- [Understanding the Problem](#understanding-the-problem)
+ - [Setup for TV SKDs](#setup-for-tv-sdks)
- [Articles](#articles)
- [react-tv-cli](#react-tv-cli)
- [Developing for WebOS](#developing-for-webos)
@@ -72,6 +73,11 @@ These restrictions make super responsive 60fps experiences especially tricky. Th
In addition: Unify the build for multiple TV platforms.
+### Setup for TV SKDs
+
+- [Setup LG WebOS SDK](docs/setup-webos-environment.md)
+- [Setup Samsung Tizen SDK](docs/setup-tizen-environment.md)
+
### Articles
Friendly list of tutorials and articles:
@@ -240,6 +246,16 @@ See [examples/navigation](examples/navigation) for more details about usage.
- http://webostv.developer.lge.com/develop/app-developer-guide/web-app-lifecycle/
- http://webostv.developer.lge.com/develop/js-services/calling-js-service/
+### Tizen
+
+- http://developer.samsung.com/tv/develop/tools/tizen-studio
+- http://developer.samsung.com/tv/develop/getting-started/setting-up-sdk/installing-tv-sdk
+- http://developer.samsung.com/tv/develop/getting-started/setting-up-sdk/creating-certificates
+- http://developer.samsung.com/tv/develop/getting-started/creating-tv-applications
+- http://developer.samsung.com/tv/design/design-principles
+- http://developer.samsung.com/tv/develop/specifications/general-specifications
+- http://developer.samsung.com/tv/develop/specifications/web-engine-specifications
+
#### Videos
##### Windows
@@ -252,7 +268,6 @@ See [examples/navigation](examples/navigation) for more details about usage.
### Essentials to beginner
-- http://developer.samsung.com/tv/develop/getting-started/setup-sdk/installing-tv-sdk/
- http://developer.samsung.com/tv/develop/getting-started/using-sdk/tv-simulator
- http://developer.samsung.com/tv/develop/getting-started/essentials-for-beginner
@@ -289,7 +304,7 @@ Implement essential functionality needed for daily use by early adopters.
- [ ] Support render to Canvas instead DOM using `React.CanvasComponent`
- [x] `run-webos` support TV device as param
- [ ] Optmizate DOMRenderer for TV
-- [ ] Start CLI for Tizen
+- [x] Start CLI for Tizen
- [x] Develop helpers for WebOS debbug (e.g: Log System).
- [x] Support Cross Platform
- [x] Check executable bin path for Windows, OSX and Linux
@@ -307,7 +322,7 @@ Add additional features users expect from a Renderer. Then fix bugs and stabiliz
- [ ] Reactive Renderer
- [ ] Testing and stability
-----------------------------------------------------
+----------------------------------------------------
See ReactTV's [Changelog](https://github.com/raphamorim/react-tv/blob/master/CHANGELOG.md).
diff --git a/docs/setup-tizen-environment.md b/docs/setup-tizen-environment.md
new file mode 100644
index 0000000..2456155
--- /dev/null
+++ b/docs/setup-tizen-environment.md
@@ -0,0 +1,13 @@
+# Setup Tizen Environment
+
+Alternative guides:
+
+- [Developing for “old” Samsung TVs in Tizen Studio 2.x](https://medium.com/@ibazzva/developing-for-old-samsung-tvs-in-tizen-studio-2-x-5aa3f853db09)
+
+[Install the Tizen Studio](http://developer.samsung.com/tv/develop/tools/tizen-studio)
+
+[Install Tizen Studio 2.1](http://download.tizen.org/sdk/Installer/tizen-studio_2.1/)
+
+[Install the TV SDK](http://developer.samsung.com/tv/develop/getting-started/setting-up-sdk/installing-tv-sdk/)
+
+Using the Package Manager install the Web CLI, Native CLI and Baseline SDK packages under the Tizen SDK Tools
diff --git a/docs/setup-webos-environment.md b/docs/setup-webos-environment.md
index 7333004..384ab66 100644
--- a/docs/setup-webos-environment.md
+++ b/docs/setup-webos-environment.md
@@ -24,6 +24,12 @@ Execute your Installer (If you're in Linux or Mac the Installer will ask for be
![Executing OSX Installer](resources/webos/1-executing-osx-installer.png)
+For OSX: Note if you doesn’t have `/opt` folder, you must to create manual.
+
+```bash
+sudo mkdir /opt
+```
+
You pop the SDK Installer, select "Agree" about LG Agreement and choose the destination folder for this installation to continue.
![WebOS Introduction](resources/webos/2-webos-introduction.png)
@@ -39,3 +45,5 @@ You'll install all packages.
After installation step, restart your machine.
![WebOS Complete](resources/webos/5-webos-complete.png)
+
+SDK Installed!
diff --git a/examples/clock-app/README.md b/examples/clock-app/README.md
index 1963c4e..a20ab62 100644
--- a/examples/clock-app/README.md
+++ b/examples/clock-app/README.md
@@ -20,8 +20,15 @@ yarn
To run it:
+WebOS:
```shell
yarn start
```
+Tizen:
+```shell
+yarn start-tizen
+```
+
+
![Screenshot](screenshot.png)
diff --git a/examples/clock-app/src/App.js b/examples/clock-app/src/App.js
index 1bf47ae..bf3df5b 100644
--- a/examples/clock-app/src/App.js
+++ b/examples/clock-app/src/App.js
@@ -16,6 +16,9 @@ class Clock extends React.Component {
if (Platform('webos'))
currentPlatform = 'LG WebOS'
+ if (Platform('tizen'))
+ currentPlatform = 'Samsung Tizen'
+
return (
diff --git a/examples/navigation/README.md b/examples/navigation/README.md
index e7c9b5f..c3dcaf9 100644
--- a/examples/navigation/README.md
+++ b/examples/navigation/README.md
@@ -26,6 +26,12 @@ yarn start-dev
To run it on TV WebOS:
+WebOS:
```shell
-yarn start
+yarn start-webos
+```
+
+Tizen:
+```shell
+yarn start-tizen
```
diff --git a/examples/navigation/package.json b/examples/navigation/package.json
index 6d5aa6f..d21e68e 100644
--- a/examples/navigation/package.json
+++ b/examples/navigation/package.json
@@ -13,9 +13,10 @@
},
"scripts": {
"build": "webpack",
- "build-prod": "NODE_ENV=production yarn build",
+ "build-prod": "cross-env NODE_ENV=production yarn build",
"react-tv-cli": "react-tv-cli",
"start": "yarn build-prod && react-tv-cli run-webos",
+ "start-tizen": "yarn build && react-tv run-tizen",
"start-dev": "webpack-dev-server --progress --colors"
},
"dependencies": {
@@ -29,6 +30,7 @@
"babel-loader": "^6.2.1",
"babel-polyfill": "^6.26.0",
"babel-preset-react": "^6.3.13",
+ "cross-env": "^5.1.1",
"webpack": "^1.12.12",
"webpack-dev-server": "^1.12.1"
}
diff --git a/packages/react-tv-cli/bootstrap/react-tv/tizen/config.xml b/packages/react-tv-cli/bootstrap/react-tv/tizen/config.xml
new file mode 100644
index 0000000..a05f053
--- /dev/null
+++ b/packages/react-tv-cli/bootstrap/react-tv/tizen/config.xml
@@ -0,0 +1,12 @@
+
+
+
+ {{REACTTVAPP}}
+
+
+
+
+
+
+
+
diff --git a/packages/react-tv-cli/index.js b/packages/react-tv-cli/index.js
index 6bde05d..2a9760c 100755
--- a/packages/react-tv-cli/index.js
+++ b/packages/react-tv-cli/index.js
@@ -2,7 +2,7 @@
const argv = process.argv;
const {help, version, createReactTVApp} = require('./shared');
-const {WebOS} = require('./scripts');
+const {WebOS, Tizen} = require('./scripts');
if (argv.length < 2) {
return help();
@@ -41,6 +41,14 @@ switch (command) {
WebOS.getKey(device);
break;
+ case 'run-tizen':
+ if (argv.length > 3) {
+ device = argv[3];
+ }
+
+ Tizen.run(process.cwd());
+ break;
+
case '--version':
version();
break;
diff --git a/packages/react-tv-cli/package.json b/packages/react-tv-cli/package.json
index e8accb5..118ce91 100644
--- a/packages/react-tv-cli/package.json
+++ b/packages/react-tv-cli/package.json
@@ -16,7 +16,8 @@
"chalk": "^2.1.0",
"fs-extra": "^4.0.3",
"node-replace": "^0.3.1",
- "node-webos": "^0.3.0"
+ "node-webos": "^0.3.0",
+ "randomstring": "^1.1.5"
},
"repository": {
"type": "git",
diff --git a/packages/react-tv-cli/scripts/tizen/index.js b/packages/react-tv-cli/scripts/tizen/index.js
new file mode 100644
index 0000000..503717d
--- /dev/null
+++ b/packages/react-tv-cli/scripts/tizen/index.js
@@ -0,0 +1,5 @@
+const run = require('./run');
+
+module.exports = {
+ run,
+};
diff --git a/packages/react-tv-cli/scripts/tizen/run.js b/packages/react-tv-cli/scripts/tizen/run.js
new file mode 100644
index 0000000..7b77d7f
--- /dev/null
+++ b/packages/react-tv-cli/scripts/tizen/run.js
@@ -0,0 +1,177 @@
+const path = require('path');
+const fs = require('fs-extra');
+const chalk = require('chalk');
+const execSync = require('child_process').execSync;
+
+function defaultCLIEnv() {
+ //return '/opt/tizen/tools/ide/bin';
+ return 'E:/Ferramentas/tizen/tools/ide/bin';
+}
+
+function getPackageId(root) {
+ const appinfo = path.resolve(root, 'react-tv/tizen/config.xml');
+ const content = fs.readFileSync(appinfo, {encoding: 'utf-8'});
+
+ const re = new RegExp(/tizen:application id="(.*?)"/);
+ const matches = content.match(re);
+
+ if (!matches) {
+ return null;
+ }
+
+ return matches[1];
+}
+
+function isReactTVTizenProject(root) {
+ const appinfo = path.resolve(root, 'react-tv/tizen/config.xml');
+ if (fs.existsSync(appinfo)) {
+ return true;
+ }
+ return false;
+}
+
+function run(root) {
+ let tizen_CLI_ENV = process.env.TIZEN_CLI || false;
+ if (!tizen_CLI_ENV) {
+ tizen_CLI_ENV = defaultCLIEnv();
+ }
+
+ process.env.PATH = `${tizen_CLI_ENV}:${process.env.PATH}`;
+
+ if (!isReactTVTizenProject(root)) {
+ const msg = `This project isn\'t a React-TV Tizen Project:
+ Just run "react-tv init"`;
+ return console.log(chalk.dim('[react-tv]'), msg);
+ }
+
+ const packageJson = require(path.resolve(root, 'package.json'));
+ const ReactTVConfig = packageJson['react-tv'];
+ if (!ReactTVConfig) {
+ return console.log(
+ chalk.dim('[react-tv]'),
+ 'You should set react-tv properties on package.json'
+ );
+ }
+
+ if (!ReactTVConfig.files || !ReactTVConfig.files.length) {
+ return console.log(chalk.dim('[react-tv]'), 'You should add files');
+ }
+
+ // TODO: option to create/select profiles?
+ const securityProfiles = execSync(
+ `${tizen_CLI_ENV}/tizen security-profiles list`
+ )
+ .toString()
+ .trim()
+ .split('\n');
+ if (!securityProfiles) {
+ return console.log(
+ chalk.dim('[react-tv]'),
+ 'No tizen security profiles found'
+ );
+ }
+
+ // Select the last profile
+ const selectedProfile = securityProfiles[securityProfiles.length - 1]
+ .split(' ', 1)[0]
+ .trim();
+
+ const tizenPath = path.resolve(root, 'react-tv/tizen');
+
+ process.on('exit', cleanup);
+ process.on('SIGINT', cleanup);
+ process.on('SIGUSR1', cleanup);
+ process.on('SIGUSR2', cleanup);
+ process.on('uncaughtException', cleanup);
+
+ function cleanup() {
+ fs.removeSync(`${tizenPath}/icon.png`);
+ ReactTVConfig.files.forEach(file => {
+ fs.removeSync(`${tizenPath}/${file}`);
+ });
+ }
+
+ try {
+ cleanup();
+ fs.copySync(`${root}/react-tv/icon-large.png`, `${tizenPath}/icon.png`);
+
+ ReactTVConfig.files.forEach(file => {
+ const filePath = path.resolve(root, file);
+ const toFile = path.resolve(tizenPath, file);
+ fs.ensureDirSync(path.dirname(toFile));
+ fs.copySync(`${filePath}`, `${toFile}`);
+ });
+ } catch (e) {
+ return console.log('FAIL TO MOUNT', e.toString());
+ }
+
+ console.log('');
+ console.log(chalk.dim('Setting up Emulator...'));
+
+ const vms = execSync(
+ `${tizen_CLI_ENV}/../../emulator/bin/em-cli list-vm`
+ ).toString();
+
+ if (vms.indexOf('react-tv-tizen') < 0) {
+ execSync(
+ `${tizen_CLI_ENV}/../../emulator/bin/em-cli create -n react-tv-tizen -p tv-samsung-3.0-x86`
+ );
+ }
+
+ const runningVms = execSync(`${tizen_CLI_ENV}/../../sdb devices`).toString();
+
+ if (runningVms.indexOf('react-tv-tizen') < 0) {
+ console.log(chalk.dim('Running Emulator...'));
+ execSync(
+ `${tizen_CLI_ENV}/../../emulator/bin/em-cli launch -n react-tv-tizen`
+ );
+ console.log(chalk.yellow(' Tizen Emulator successful running'));
+ } else {
+ console.log(chalk.yellow(' already running.'));
+ }
+
+ console.log(chalk.dim('Packing...'));
+ execSync(
+ `cd ${tizenPath} && ${tizen_CLI_ENV}/tizen package -t wgt -s ${selectedProfile}`
+ );
+ console.log(chalk.yellow(` succefull pack from ${root}`));
+
+ console.log(chalk.dim('Running App...'));
+
+ let attemps = 0;
+ const task = setInterval(function() {
+ if (attemps > 15) {
+ console.log('FAILED TO UP Tizen emulator');
+ clearInterval(task);
+ }
+
+ try {
+ execSync(`${tizen_CLI_ENV}/../../sdb devices`).toString();
+
+ execSync(
+ `cd ${tizenPath} && ${tizen_CLI_ENV}/tizen install -n ${
+ packageJson.name
+ }.wgt -t react-tv-tizen`
+ );
+ } catch (error) {
+ if (error.stdout.toString().indexOf('install completed') < 0) {
+ attemps += 1;
+ return false;
+ }
+ }
+
+ clearInterval(task);
+
+ const packageId = getPackageId(root);
+
+ if (!packageId) {
+ return console.log('Invalid package id!');
+ }
+
+ execSync(
+ `cd ${tizenPath} && ${tizen_CLI_ENV}/tizen run -p ${packageId} -t react-tv-tizen`
+ );
+ }, 500);
+}
+
+module.exports = run;
diff --git a/packages/react-tv-cli/shared/index.js b/packages/react-tv-cli/shared/index.js
index add9c2a..2b88cca 100644
--- a/packages/react-tv-cli/shared/index.js
+++ b/packages/react-tv-cli/shared/index.js
@@ -2,6 +2,7 @@ const fs = require('fs-extra');
const path = require('path');
const chalk = require('chalk');
const replace = require('node-replace');
+const randomstring = require('randomstring');
function debug(msg) {
console.log(chalk.dim('[react-tv]'), msg);
@@ -48,6 +49,7 @@ https://medium.com/@raphamorim/developing-for-tvs-with-react-tv-b5b5204964ef`)
}
function createReactTVApp(appName) {
+ console.log('tizen');
let appPath = process.cwd();
const packageJson = path.resolve(appPath, 'package.json');
@@ -66,6 +68,22 @@ function createReactTVApp(appName) {
recursive: true,
silent: true,
});
+
+ replace({
+ regex: '{{TIZEN_PACKAGE}}',
+ replacement: randomstring.generate(10),
+ paths: [appName],
+ recursive: true,
+ silent: true,
+ });
+
+ replace({
+ regex: '{{TIZEN_REACTTVAPP}}',
+ replacement: appName.replace(/-/g, '').replace(/\./g, ''),
+ paths: [appName],
+ recursive: true,
+ silent: true,
+ });
} catch (e) {
return process.exit(1);
}
@@ -96,6 +114,22 @@ function createReactTVApp(appName) {
recursive: true,
silent: true,
});
+
+ replace({
+ regex: '{{TIZEN_PACKAGE}}',
+ replacement: randomstring.generate(10),
+ paths: ['./react-tv/tizen'],
+ recursive: true,
+ silent: true,
+ });
+
+ replace({
+ regex: '{{TIZEN_REACTTVAPP}}',
+ replacement: appName.replace(/-/g, '').replace(/\./g, ''),
+ paths: ['./react-tv/tizen'],
+ recursive: true,
+ silent: true,
+ });
} catch (e) {
return process.exit(1);
}
diff --git a/packages/react-tv/modules/Platform.js b/packages/react-tv/modules/Platform.js
index c700f52..7c91a7e 100644
--- a/packages/react-tv/modules/Platform.js
+++ b/packages/react-tv/modules/Platform.js
@@ -12,7 +12,7 @@ function isLGWebOS() {
}
function isSamsungTizen() {
- return false;
+ return !!(window && window.tizen);
}
function isSamsungOrsay() {