@@ -211,6 +211,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
@@ -223,7 +233,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
@@ -260,7 +269,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
@@ -278,7 +287,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..1f98574
--- /dev/null
+++ b/docs/setup-tizen-environment.md
@@ -0,0 +1,7 @@
+# Setup Tizen Environment
+
+[Install the Tizen Studio](http://developer.samsung.com/tv/develop/tools/tizen-studio)
+
+[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/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
+```
+
+

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/package.json b/examples/navigation/package.json
index 5dabbaa..c61757a 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-webos": "yarn build-prod && react-tv-cli run-webos",
+ "start-tizen": "yarn build-prod && react-tv-cli run-tizen",
"start-dev": "webpack-dev-server --progress --colors"
},
"dependencies": {
@@ -28,6 +29,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..8ab5884
--- /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..a8845c5 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 ae76fa6..88f4e26 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/index.js b/packages/react-tv-cli/scripts/index.js
index 8135004..3b8ed37 100644
--- a/packages/react-tv-cli/scripts/index.js
+++ b/packages/react-tv-cli/scripts/index.js
@@ -1,5 +1,7 @@
const WebOS = require('./webos');
+const Tizen = require('./tizen');
module.exports = {
WebOS,
+ Tizen,
};
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..c6f3ada
--- /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..dc3cf30
--- /dev/null
+++ b/packages/react-tv-cli/scripts/tizen/run.js
@@ -0,0 +1,183 @@
+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 1311db8..ac08b9d 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);
@@ -25,6 +26,10 @@ function help() {
chalk.bgBlueBright(' run-webos '),
chalk.blueBright(' pack, build and runs webos simulator')
);
+ console.log(
+ chalk.bgBlueBright(' run-tizen '),
+ chalk.blueBright(' pack, build and runs tizen emulator')
+ );
console.log(
chalk.bgRed(' help '),
chalk.red(' output react-tv cli commands')
@@ -32,6 +37,7 @@ function help() {
}
function createReactTVApp(appName) {
+ console.log('tizen');
let appPath = process.cwd();
const packageJson = path.resolve(appPath, 'package.json');
@@ -50,6 +56,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);
}
@@ -80,6 +102,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..59b70ce 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 tizen ? true : false;
}
function isSamsungOrsay() {