Skip to content
This repository has been archived by the owner on Mar 26, 2024. It is now read-only.

Add support to Tizen #54

Closed
wants to merge 16 commits into from
21 changes: 15 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ In addition: Unify the build for multiple TV platforms.

### Articles

Friendly list of tutorials and articles:
Friendly list of tutorials and articles:

- [Developing for TVs with React-TV](https://medium.com/@raphamorim/developing-for-tvs-with-react-tv-b5b5204964ef)

Expand Down Expand Up @@ -163,9 +163,9 @@ const App = renderOnAppLoaded(Component)

### Spatial Navigation

React-TV provides a spatial navigation system on render level.
React-TV provides a spatial navigation system on render level.

Just add `focusable` for navigable elements and `focused` for an element which starts focused.
Just add `focusable` for navigable elements and `focused` for an element which starts focused.

```jsx
<div>
Expand Down Expand Up @@ -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
Expand All @@ -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

Expand Down Expand Up @@ -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
Expand All @@ -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).

Expand Down
7 changes: 7 additions & 0 deletions docs/setup-tizen-environment.md
Original file line number Diff line number Diff line change
@@ -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
7 changes: 7 additions & 0 deletions examples/clock-app/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,15 @@ yarn

To run it:

WebOS:
```shell
yarn start
```

Tizen:
```shell
yarn start-tizen
```


![Screenshot](screenshot.png)
3 changes: 3 additions & 0 deletions examples/clock-app/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ class Clock extends React.Component {
if (Platform('webos'))
currentPlatform = 'LG WebOS'

if (Platform('tizen'))
currentPlatform = 'Samsung Tizen'

return (
<div class='container'>
<img src='https://i.imgur.com/9yhDR0Q.png'/>
Expand Down
6 changes: 4 additions & 2 deletions examples/navigation/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand All @@ -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"
}
Expand Down
12 changes: 12 additions & 0 deletions packages/react-tv-cli/bootstrap/react-tv/tizen/config.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<widget xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets" id="http://yourdomain/Template01" version="0.2.1" viewmodes="maximized">
<tizen:application id="{{TIZEN_PACKAGE}}.{{TIZEN_REACTTVAPP}}" package="{{TIZEN_PACKAGE}}" required_version="2.3"/>
<name>{{REACTTVAPP}}</name>
<icon src="icon.png"/>
<tizen:privilege name="http://tizen.org/privilege/application.launch"/>
<content src="index.html"/>
<feature name="http://tizen.org/feature/screen.size.normal.1080.1920"/>
<tizen:metadata key="http://samsung.com/tv/metadata/prelaunch.support" value="true"/>
<tizen:profile name="tv"/>
<tizen:setting background-support="disable" context-menu="enable" encryption="disable" hwkey-event="enable" install-location="auto" screen-orientation="landscape"/>
</widget>
10 changes: 9 additions & 1 deletion packages/react-tv-cli/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion packages/react-tv-cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
2 changes: 2 additions & 0 deletions packages/react-tv-cli/scripts/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
const WebOS = require('./webos');
const Tizen = require('./tizen');

module.exports = {
WebOS,
Tizen,
};
5 changes: 5 additions & 0 deletions packages/react-tv-cli/scripts/tizen/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const run = require('./run');

module.exports = {
run
};
183 changes: 183 additions & 0 deletions packages/react-tv-cli/scripts/tizen/run.js
Original file line number Diff line number Diff line change
@@ -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;
Loading