diff --git a/client/config.xml b/client/config.xml
index c48e640..764b47b 100644
--- a/client/config.xml
+++ b/client/config.xml
@@ -1,5 +1,5 @@
-
+
Reis Can
@@ -20,4 +20,4 @@
TizenBrewService
-
\ No newline at end of file
+
diff --git a/client/package.json b/client/package.json
index 661c050..db4a776 100644
--- a/client/package.json
+++ b/client/package.json
@@ -7,11 +7,11 @@
"services/tizenbrew-installer-service/dist/**"
],
"targets": [
- "node20-linux-x64",
- "node20-win-x64",
- "node20-macos-arm64",
- "node20-macos-x64",
- "node20-linux-arm64"
+ "node22-linux-x64",
+ "node22-win-x64",
+ "node22-macos-arm64",
+ "node22-macos-x64",
+ "node22-linux-arm64"
],
"outputPath": "dist"
}
diff --git a/client/services/tizenbrew-installer-service/index.js b/client/services/tizenbrew-installer-service/index.js
index 49801c4..a09135b 100644
--- a/client/services/tizenbrew-installer-service/index.js
+++ b/client/services/tizenbrew-installer-service/index.js
@@ -1,6 +1,12 @@
"use strict";
const isTV = typeof tizen !== 'undefined';
+// Required due to svdca.samsungqbe.com certificate expiring and Samsung not doing anything.
+// Also for older Tizen TVs who had their root certificate break.
+process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
+
+// To remove the DeprecationWarning displayed.
+process.removeAllListeners('warning');
module.exports.onStart = function () {
console.log('Service started');
@@ -38,6 +44,13 @@ module.exports.onStart = function () {
app.use(express.static(`${process.platform === 'win32' ? 'C:\\' : '/'}snapshot/client`));
} else app.use(express.static(join(__dirname, '../../')));
}
+
+ app.get('/ui/dist/index.html/desktop', (_, res) => {
+ if (existsSync(`${process.platform === 'win32' ? 'C:\\' : '/'}snapshot/client`)) {
+ res.sendFile(`${process.platform === 'win32' ? 'C:\\' : '/'}snapshot/client/ui/dist/index.html`);
+ } else res.sendFile((join(__dirname, '../../ui/dist/index.html')));
+ });
+
let isTizen7OrHigher = isTV && Number(tizen.systeminfo.getCapability('http://tizen.org/feature/platform.version').split('.')[0]) >= 7;
const isTizen3 = isTV && tizen.systeminfo.getCapability('http://tizen.org/feature/platform.version').startsWith('3.0');
const wsServer = new WebSocket.Server({ server: app.listen(8091) });
@@ -125,78 +138,116 @@ module.exports.onStart = function () {
return wsConn.send(wsConn.Event(Events.Error, `Invalid JSON: ${message}`));
}
- const { type, payload } = msg;
+ function parseAndInstall(buffer) {
+ parsePackage(buffer)
+ .then(pkg => {
+ wsConn.send(wsConn.Event(Events.InstallationStatus, 'installStatus.installing'));
+ if (isTV) {
+ if (!existsSync('/home/owner/share/tmp/sdk_tools')) mkdirRecursive(`/home/owner/share/tmp/sdk_tools`);
+ writeFileSync(`/home/owner/share/tmp/sdk_tools/package.${pkg.isWgt ? 'wgt' : 'tpk'}`, buffer);
+ } else {
+ PushFile(adbClient, `/home/owner/share/tmp/sdk_tools/package.${pkg.isWgt ? 'wgt' : 'tpk'}`, buffer, () => {
+ installPackage(`/home/owner/share/tmp/sdk_tools/package.${pkg.isWgt ? 'wgt' : 'tpk'}`, pkg.packageId, adbClient)
+ .then(result => {
+ wsConn.send(wsConn.Event(Events.InstallationStatus, 'installStatus.installed'));
+ wsConn.send(wsConn.Event(Events.InstallPackage, { response: 0, result }));
+ });
+ });
+ return;
+ }
- switch (type) {
- case Events.InstallPackage: {
- if (!isTizen3 && isTV) {
- if (canConnectToDevice !== null && !canConnectToDevice) {
- return wsConn.send(wsConn.Event(Events.Error, 'errors.debuggingNotEnabled'));
- } else if (canConnectToDevice === null) return;
- }
- if (isTizen7OrHigher) {
- // Check if we have author and distributor certificates
- const config = readConfig();
- if (!config.authorCert || !config.distributorCert || !config.password) {
- return wsConn.send(wsConn.Event(Events.InstallPackage, { response: 2 }));
+ if (payload.url && payload.url === 'reisxd/TizenBrewInstaller' &&
+ !isTV && existsSync(`${homedir()}/share/tizenbrewInstallerConfig.json`)) {
+ // Send the existing config to the TV
+ PushFile(adbClient, '/home/owner/share/tizenbrewInstallerConfig.json', readFileSync(`${homedir()}/share/tizenbrewInstallerConfig.json`), () => {
+ console.log('Config pushed to TV for Installer');
+ });
}
- }
- function parseAndInstall(buffer) {
- parsePackage(buffer)
- .then(pkg => {
- wsConn.send(wsConn.Event(Events.InstallationStatus, 'installStatus.installing'));
- if (isTV) {
- if (!existsSync('/home/owner/share/tmp/sdk_tools')) mkdirRecursive(`/home/owner/share/tmp/sdk_tools`);
- writeFileSync(`/home/owner/share/tmp/sdk_tools/package.${pkg.isWgt ? 'wgt' : 'tpk'}`, buffer);
- } else {
- PushFile(adbClient, `/home/owner/share/tmp/sdk_tools/package.${pkg.isWgt ? 'wgt' : 'tpk'}`, buffer, () => {
- installPackage(`/home/owner/share/tmp/sdk_tools/package.${pkg.isWgt ? 'wgt' : 'tpk'}`, pkg.packageId, adbClient)
- .then(result => {
- wsConn.send(wsConn.Event(Events.InstallationStatus, 'installStatus.installed'));
- wsConn.send(wsConn.Event(Events.InstallPackage, { response: 0, result }));
- });
- });
- return;
- }
-
- if (payload.url && payload.url === 'reisxd/TizenBrewInstaller' &&
- !isTV && existsSync(`${homedir()}/share/tizenbrewInstallerConfig.json`)) {
- // Send the existing config to the TV
- PushFile(adbClient, '/home/owner/share/tizenbrewInstallerConfig.json', readFileSync(`${homedir()}/share/tizenbrewInstallerConfig.json`), () => {
- console.log('Config pushed to TV for Installer');
- });
- }
-
- if (isTizen3 && isTV) {
- const result = installPackage(`/home/owner/share/tmp/sdk_tools/package.${pkg.isWgt ? 'wgt' : 'tpk'}`, pkg.packageId);
- setValue('db/sdk/develop/ip', 'string', '127.0.0.1');
- setValue('db/sdk/develop/mode', 'int32', '1');
- wsConn.send(wsConn.Event(Events.InstallationStatus, 'installStatus.installed'));
- wsConn.send(wsConn.Event(Events.InstallPackage, { response: 0, result }));
- } else if (isTV) {
- createAdbConnection()
- .then(adbClient => {
- installPackage(`/home/owner/share/tmp/sdk_tools/package.${pkg.isWgt ? 'wgt' : 'tpk'}`, pkg.packageId, adbClient)
- .then(result => {
- wsConn.send(wsConn.Event(Events.InstallationStatus, 'installStatus.installed'));
- wsConn.send(wsConn.Event(Events.InstallPackage, { response: 0, result }));
- setTimeout(() => {
- adbClient._stream.end();
- adbClient._stream.destroy();
- }, 5000);
- });
- })
- .catch(err => {
- wsConn.send(wsConn.Event(Events.Error, err.message.includes('.') ? err.message : `Error creating ADB connection: ${err.message}`));
+ if (isTizen3 && isTV) {
+ const result = installPackage(`/home/owner/share/tmp/sdk_tools/package.${pkg.isWgt ? 'wgt' : 'tpk'}`, pkg.packageId);
+ setValue('db/sdk/develop/ip', 'string', '127.0.0.1');
+ setValue('db/sdk/develop/mode', 'int32', '1');
+ wsConn.send(wsConn.Event(Events.InstallationStatus, 'installStatus.installed'));
+ wsConn.send(wsConn.Event(Events.InstallPackage, { response: 0, result }));
+ } else if (isTV) {
+ createAdbConnection()
+ .then(adbClient => {
+ installPackage(`/home/owner/share/tmp/sdk_tools/package.${pkg.isWgt ? 'wgt' : 'tpk'}`, pkg.packageId, adbClient)
+ .then(result => {
+ wsConn.send(wsConn.Event(Events.InstallationStatus, 'installStatus.installed'));
+ wsConn.send(wsConn.Event(Events.InstallPackage, { response: 0, result }));
+ setTimeout(() => {
+ adbClient._stream.end();
+ adbClient._stream.destroy();
+ }, 5000);
});
- }
- })
- .catch(err => {
- wsConn.send(wsConn.Event(Events.Error, `Error parsing package: ${err.message}`));
- console.error(err);
- });
+ })
+ .catch(err => {
+ wsConn.send(wsConn.Event(Events.Error, err.message.includes('.') ? err.message : `Error creating ADB connection: ${err.message}`));
+ });
+ }
+ })
+ .catch(err => {
+ wsConn.send(wsConn.Event(Events.Error, `Error parsing package: ${err.message}`));
+ console.error(err);
+ });
+ }
+
+ function resignOrInstall(buffer) {
+ if (isTizen7OrHigher) {
+ const config = readConfig();
+ const certificates = {
+ authorCert: Buffer.from(config.authorCert, 'base64').toString('binary'),
+ distributorCert: Buffer.from(config.distributorCert, 'base64').toString('binary'),
+ password: config.password
+ };
+
+ wsConn.send(wsConn.Event(Events.InstallationStatus, 'installStatus.resigning'));
+ resignPackage(certificates, buffer)
+ .then(resignedBuffer => {
+ wsConn.send(wsConn.Event(Events.InstallationStatus, 'installStatus.parsing'));
+ parseAndInstall(resignedBuffer);
+ })
+ .catch(err => {
+ wsConn.send(wsConn.Event(Events.Error, `Error resigning package: ${err.message}`));
+ });
+ } else {
+ wsConn.send(wsConn.Event(Events.InstallationStatus, 'installStatus.parsing'));
+ parseAndInstall(buffer);
+ }
+ }
+
+ function checkPrecondition() {
+ if (!isTizen3 && isTV) {
+ if (canConnectToDevice !== null && !canConnectToDevice) {
+ wsConn.send(wsConn.Event(Events.Error, 'errors.debuggingNotEnabled'));
+ return false;
+ } else if (canConnectToDevice === null) return false;
+ }
+ if (isTizen7OrHigher) {
+ // Check if we have author and distributor certificates
+ const config = readConfig();
+ if (!config.authorCert || !config.distributorCert || !config.password) {
+ wsConn.send(wsConn.Event(Events.InstallPackage, { response: 2 }));
+ return false;
}
+ }
+
+ if (!isTV && (!adbClient || !isConnected)) {
+ // Somethings wrong.
+ wsConn.send(wsConn.Event(Events.ConnectToTV, { success: false }))
+ return false;
+ }
+
+ return true;
+ }
+
+ const { type, payload } = msg;
+
+ switch (type) {
+ case Events.InstallPackage: {
+ if (!checkPrecondition()) return;
if (payload.url.split('/').length === 2) {
// GitHub repository
@@ -207,24 +258,7 @@ module.exports.onStart = function () {
fetch(asset.browser_download_url)
.then(res => res.buffer())
.then(buffer => {
- if (isTizen7OrHigher) {
- wsConn.send(wsConn.Event(Events.InstallationStatus, 'installStatus.resigning'));
- const config = readConfig();
- const certificates = {
- authorCert: Buffer.from(config.authorCert, 'base64').toString('binary'),
- distributorCert: Buffer.from(config.distributorCert, 'base64').toString('binary'),
- password: config.password
- };
-
- resignPackage(certificates, buffer)
- .then(resignedBuffer => {
- wsConn.send(wsConn.Event(Events.InstallationStatus, 'installStatus.parsing'));
- parseAndInstall(resignedBuffer);
- })
- .catch(err => {
- wsConn.send(wsConn.Event(Events.Error, `Error resigning package: ${err.message}`));
- });
- } else parseAndInstall(buffer);
+ resignOrInstall(buffer)
})
.catch(err => {
wsConn.send(wsConn.Event(Events.Error, `Error fetching release asset: ${err.message}`));
@@ -235,27 +269,7 @@ module.exports.onStart = function () {
} else {
// USB installation
const fileBuffer = readFileSync(payload.url);
- if (isTizen7OrHigher) {
- const config = readConfig();
- const certificates = {
- authorCert: Buffer.from(config.authorCert, 'base64').toString('binary'),
- distributorCert: Buffer.from(config.distributorCert, 'base64').toString('binary'),
- password: config.password
- };
-
- wsConn.send(wsConn.Event(Events.InstallationStatus, 'installStatus.resigning'));
- resignPackage(certificates, fileBuffer)
- .then(resignedBuffer => {
- wsConn.send(wsConn.Event(Events.InstallationStatus, 'installStatus.parsing'));
- parseAndInstall(resignedBuffer);
- })
- .catch(err => {
- wsConn.send(wsConn.Event(Events.Error, `Error resigning package: ${err.message}`));
- });
- } else {
- wsConn.send(wsConn.Event(Events.InstallationStatus, 'installStatus.parsing'));
- parseAndInstall(fileBuffer);
- }
+ resignOrInstall(fileBuffer);
}
break;
@@ -282,6 +296,11 @@ module.exports.onStart = function () {
wsConn.send(wsConn.Event(Events.NavigateDirectory, metadata));
break;
}
+ case Events.InstallFile: {
+ if (!checkPrecondition()) return;
+ const fileBuffer = Buffer.from(payload, 'base64');
+ resignOrInstall(fileBuffer);
+ }
case Events.DeleteConfiguration: {
const config = readConfig();
config.authorCert = null;
@@ -342,7 +361,7 @@ module.exports.onStart = function () {
privilegeLevel: 'Partner'
};
- function createCert(adbClient) {
+ function createCert() {
createSamsungCertificate(authorInfo, accessInfo, adbClient, isTV)
.then(certificate => {
const currentConfig = readConfig();
@@ -371,12 +390,15 @@ module.exports.onStart = function () {
if (isTV) {
if (!adbClient && !isConnected) {
createAdbConnection().then(adbClient => {
- createCert(adbClient);
+ createCert();
}).catch(err => {
response.status(500).json({ error: err.message });
});
- } else createCert(adbClient);
- } else createCert(adbClient);
+ } else createCert();
+ } else if (!adbClient || !isConnected) {
+ response.send('Connection between the TV and the device was broken. Please reconnect to your TV from the previous page and try again.');
+ if (wsClient) wsClient.send(wsClient.Event(Events.ConnectToTV, { success: false }))
+ } else createCert();
} else {
response.send(AccessInfoHTMLPage);
}
diff --git a/client/services/tizenbrew-installer-service/utils/wsCommunication.js b/client/services/tizenbrew-installer-service/utils/wsCommunication.js
index 50febfb..d533e3c 100644
--- a/client/services/tizenbrew-installer-service/utils/wsCommunication.js
+++ b/client/services/tizenbrew-installer-service/utils/wsCommunication.js
@@ -22,7 +22,8 @@ const Events = {
Error: 3,
InstallationStatus: 4,
DeleteConfiguration: 5,
- ConnectToTV: 6
+ ConnectToTV: 6,
+ InstallFile: 7
};
module.exports = {
diff --git a/client/ui/src/components/ClientContext.jsx b/client/ui/src/components/ClientContext.jsx
index 6cde4a3..7d423a9 100644
--- a/client/ui/src/components/ClientContext.jsx
+++ b/client/ui/src/components/ClientContext.jsx
@@ -3,6 +3,7 @@ import { useReducer } from 'preact/hooks';
const initialState = {
sharedData: {
+ tizenBrewRepo: localStorage.getItem('tizenBrewRepo') || 'reisxd/TizenBrew',
state: null,
directory: [],
error: {
@@ -32,6 +33,9 @@ function reducer(state, action) {
return { ...state, sharedData: { ...state.sharedData, qrCodeShow: action.payload } };
case 'SET_CONNECTED_TO_TV':
return { ...state, sharedData: { ...state.sharedData, connectedToTV: action.payload } };
+ case 'SET_TIZENBREW_REPO':
+ localStorage.setItem('tizenBrewRepo', action.payload);
+ return { ...state, sharedData: { ...state.sharedData, tizenBrewRepo: action.payload } };
default:
return state;
}
diff --git a/client/ui/src/components/WebSocketClient.js b/client/ui/src/components/WebSocketClient.js
index cc0c323..5c5e1ce 100644
--- a/client/ui/src/components/WebSocketClient.js
+++ b/client/ui/src/components/WebSocketClient.js
@@ -6,7 +6,8 @@ const Events = {
Error: 3,
InstallationStatus: 4,
DeleteConfiguration: 5,
- ConnectToTV: 6
+ ConnectToTV: 6,
+ InstallFile: 7
};
class Client {
diff --git a/client/ui/src/components/i18nResources.js b/client/ui/src/components/i18nResources.js
index 69d81d7..4406aa6 100644
--- a/client/ui/src/components/i18nResources.js
+++ b/client/ui/src/components/i18nResources.js
@@ -3,12 +3,16 @@ import FrenchLanguage from '../lang/fr.json';
import SerbianLanguage from '../lang/sr.json';
import TurkishLanguage from '../lang/tr.json';
import VietnameseLanguage from '../lang/vi.json';
-import DutchLanguage from '../lang/nl.json';
+import DutchLanguage from '../lang/nl.json';
+import GermanLanguage from '../lang/de.json';
const resources = {
en: {
translation: EnglishLanguage
},
+ de: {
+ translation: GermanLanguage
+ },
fr: {
translation: FrenchLanguage
},
diff --git a/client/ui/src/lang/de.json b/client/ui/src/lang/de.json
new file mode 100644
index 0000000..2b361c7
--- /dev/null
+++ b/client/ui/src/lang/de.json
@@ -0,0 +1,43 @@
+{
+ "service": {
+ "alreadyRunning": "Der Dienst läuft bereits.",
+ "started": "Dienst gestartet."
+ },
+ "errors": {
+ "debuggingNotEnabled": "Fehler: Verbindung zum SDB-Daemon konnte nicht hergestellt werden. Hast du die Host-PC-IP wirklich auf 127.0.0.1 geändert? Falls ja, halte den Einschaltknopf gedrückt, bis das Samsung-Logo erscheint."
+ },
+ "installStatus": {
+ "fetching": "Paket wird abgerufen",
+ "resigning": "Paket wird neu signiert",
+ "parsing": "Paket wird verarbeitet",
+ "installing": "Paket wird installiert",
+ "installed": "Paket installiert",
+ "installFailed": "Installation fehlgeschlagen: {{line}}"
+ },
+ "resigning": {
+ "resigningRequired": "Neu-Signierung erforderlich",
+ "resigningRequiredDesc": "Seit Tizen 7 müssen alle Pakete mit einem Samsung-Zertifikat neu signiert werden.\nBitte scanne den QR-Code, um dich bei deinem Samsung-Konto anzumelden, und kopiere anschließend die JSON-Antwort, die du nach der Anmeldung erhältst.",
+ "resigningRequiredPCDesc": "Seit Tizen 7 müssen alle Pakete mit einem Samsung-Zertifikat neu signiert werden.\nBitte klicke auf die Schaltfläche unten, um dich bei deinem Samsung-Konto anzumelden.",
+ "resigningRequiredOpenAuthButton": "Bei Samsung-Konto anmelden",
+ "resigningRequiredAccessInfo": "Nachdem du die JSON-Antwort kopiert hast, gehe zu http://{{ip}}:4794, füge sie in das Eingabefeld ein und drücke die Schaltfläche \"Submit\".",
+ "resigningDeviceSameNetwork": "Stelle sicher, dass sich dein Gerät im selben Netzwerk wie dein Fernseher befindet."
+ },
+ "installer": {
+ "installTB": "TizenBrew installieren",
+ "installTBI": "TizenBrew Installer installieren",
+ "connectToTV": "Mit Fernseher verbinden",
+ "updateTB": "TizenBrew aktualisieren",
+ "installFromUSB": "Von USB installieren",
+ "installFromGH": "Von GitHub installieren",
+ "selectToInstall": "Datei zur Installation auswählen",
+ "installingAgain": "TizenBrew Installer ist als USB-Demopaket installiert. Es wird jetzt als normales Paket neu installiert.",
+ "alreadyInstalled": "TizenBrew Installer ist als USB-Demopaket installiert. Du kannst es jetzt deinstallieren."
+ },
+ "installerDesktop": {
+ "sdbConnectionRefused": "Verbindung zum SDB-Daemon konnte nicht hergestellt werden. Stelle sicher, dass der Fernseher eingeschaltet ist und die IP korrekt ist.",
+ "sdbConnectionReset": "Verbindung zum SDB-Daemon konnte nicht hergestellt werden. Entweder wurde die Host-PC-IP nicht auf die IP dieses Geräts gesetzt, oder der Fernseher wurde nicht richtig neu gestartet. Halte den Einschaltknopf gedrückt, bis das Samsung-Logo erscheint, um den Fernseher neu zu starten."
+ },
+ "__contributors": [
+ "KrX3D"
+ ]
+}
diff --git a/client/ui/src/lang/en.json b/client/ui/src/lang/en.json
index 72bfceb..7042f45 100644
--- a/client/ui/src/lang/en.json
+++ b/client/ui/src/lang/en.json
@@ -29,6 +29,7 @@
"updateTB": "Update TizenBrew",
"installFromUSB": "Install from USB",
"installFromGH": "Install from GitHub",
+ "selectToInstall": "Select file to install",
"installingAgain": "TizenBrew Installer is installed as an USB Demo Package. It will now be reinstalled as a normal package.",
"alreadyInstalled": "TizenBrew Installer as an USB Demo Package is installed. You can now uninstall it."
},
diff --git a/client/ui/src/lang/fr.json b/client/ui/src/lang/fr.json
index fd30029..55bb47d 100644
--- a/client/ui/src/lang/fr.json
+++ b/client/ui/src/lang/fr.json
@@ -25,6 +25,7 @@
"updateTB": "Mettre à jour TizenBrew",
"installFromUSB": "Installer à partir d'un périphérique USB",
"installFromGH": "Installer depuis GitHub",
+ "selectToInstall": "Sélectionner un fichier à installer",
"installingAgain": "TizenBrew Installer est installé en tant que Paquet Démo USB. Il va maintenant être réinstallé en tant que paquet normal.",
"alreadyInstalled": "Le Paquet Démo USB de TizenBrew Installer est installé. Vous pouvez maintenant le supprimer."
},
diff --git a/client/ui/src/lang/nl.json b/client/ui/src/lang/nl.json
index fe1d5d9..b4a7172 100644
--- a/client/ui/src/lang/nl.json
+++ b/client/ui/src/lang/nl.json
@@ -25,6 +25,7 @@
"updateTB": "TizenBrew updaten",
"installFromUSB": "Installeren van USB",
"installFromGH": "Installeren van GitHub",
+ "selectToInstall": "Selecteer bestand om te installeren",
"installingAgain": "TizenBrew Installer is geinstalleerd als een USB Demo Package. Het zal nu worden geinstalleerd als een normaal pakket.",
"alreadyInstalled": "TizenBrew Installer als een USB Demo Package is geinstalleerd. U kunt het nu verwijderen."
},
diff --git a/client/ui/src/lang/sr.json b/client/ui/src/lang/sr.json
index 7ffc2af..8a22bb4 100644
--- a/client/ui/src/lang/sr.json
+++ b/client/ui/src/lang/sr.json
@@ -25,6 +25,7 @@
"updateTB": "Ажурирање TizenBrew",
"installFromUSB": "Инсталација са USB флешке",
"installFromGH": "Инсталација са GitHub-а",
+ "selectToInstall": "Изабери фајл за инсталацију",
"installingAgain": "TizenBrew Installer је инсталиран као USB Demo пакет. Сада ће бити поново инсталиран као обичан пакет.",
"alreadyInstalled": "TizenBrew Installer као USB Demo пакет је инсталиран. Сада га можете деинсталирати."
},
diff --git a/client/ui/src/lang/tr.json b/client/ui/src/lang/tr.json
index b22b447..01afc1c 100644
--- a/client/ui/src/lang/tr.json
+++ b/client/ui/src/lang/tr.json
@@ -29,6 +29,7 @@
"updateTB": "TizenBrew'ı Güncelle",
"installFromUSB": "USB'den Kur",
"installFromGH": "GitHub'dan Kur",
+ "selectToInstall": "Kurmak için dosyas seç",
"installingAgain": "TizenBrew Installer, USB Demo paketi olarak yüklüdür. Şimdi normal paket olarak yeniden yüklenecektir.",
"alreadyInstalled": "TizenBrew Installer, USB Demo paketi olarak yüklüdür. Şimdi USB Demo paketini kaldırabilirsiniz."
},
diff --git a/client/ui/src/lang/vi.json b/client/ui/src/lang/vi.json
index ef52916..2742eb4 100644
--- a/client/ui/src/lang/vi.json
+++ b/client/ui/src/lang/vi.json
@@ -25,6 +25,7 @@
"updateTB": "Cập nhật TizenBrew",
"installFromUSB": "Cài đặt app từ USB",
"installFromGH": "Cài đặt app từ GitHub",
+ "selectToInstall": "Chọn file để cài đặt",
"installingAgain": "TizenBrew Installer đã được cài đặt dưới dạng USB Demo Package. Bây giờ app sẽ tự cài lại như 1 app bình thường.",
"alreadyInstalled": "TizenBrew Installer dưới dạng USB Demo Package đang được cài đặt. Bây giờ bạn có thể gỡ cài đặt gói Demo này."
},
diff --git a/client/ui/src/pages/Desktop.jsx b/client/ui/src/pages/Desktop.jsx
index 7c60bb7..489d0d5 100644
--- a/client/ui/src/pages/Desktop.jsx
+++ b/client/ui/src/pages/Desktop.jsx
@@ -23,8 +23,28 @@ export default function Desktop() {
}
}, [context.state.client, context.state.client?.socket?.readyState]);
+ function onInputChange(event) {
+ const file = event.target.files[0];
+ if (file) {
+ const reader = new FileReader();
+ reader.onload = (e) => {
+ const dataUrl = e.target.result;
+
+ const base64Data = dataUrl.split(',')[1];
+
+ context.state.client.send({
+ type: Events.InstallFile,
+ payload: base64Data
+ });
+ }
+
+ reader.readAsDataURL(file);
+ }
+ }
+
return (
+
{context.state.sharedData.qrCodeShow && (
@@ -48,7 +68,7 @@ export default function Desktop() {
context.state.client.send({
type: Events.InstallPackage,
payload: {
- url: 'reisxd/TizenBrew'
+ url: context.state.sharedData.tizenBrewRepo
}
})
}}>
@@ -84,6 +104,17 @@ export default function Desktop() {
+
- {
+ const realFileInput = document.getElementById('realFileInput');
+ realFileInput.click();
+ }}>
+
+
+
+ {t('installer.selectToInstall')}
+
+
+
>
) : (
-
@@ -100,6 +131,7 @@ export default function Desktop() {
className="w-full p-2 rounded-lg bg-gray-800 text-gray-200"
onChange={(e) => setIp(e.target.value)}
onKeyDown={(e) => {
+ if (e.keyCode === 37 || e.keyCode === 39) { e.stopPropagation(); return; }
if (e.keyCode === 13 || e.keyCode === 65376) {
ipInputRef.current.blur();
}
diff --git a/client/ui/src/pages/Home.jsx b/client/ui/src/pages/Home.jsx
index 3e8774f..3e4d424 100644
--- a/client/ui/src/pages/Home.jsx
+++ b/client/ui/src/pages/Home.jsx
@@ -19,11 +19,13 @@ export default function Home() {
// Check if TizenBrew is already installed.
let isTizenBrewInstalled = false;
+ let installedVersion = null;
try {
- tizen.application.getAppInfo('xvvl3S1bvH.TizenBrewStandalone');
+ const appInfo = tizen.application.getAppInfo('xvvl3S1bvH.TizenBrewStandalone');
isTizenBrewInstalled = true;
+ installedVersion = appInfo.version;
} catch (e) { }
-
+
useEffect(() => {
if (
@@ -73,7 +75,7 @@ export default function Home() {
context.state.client.send({
type: Events.InstallPackage,
payload: {
- url: 'reisxd/TizenBrew'
+ url: context.state.sharedData.tizenBrewRepo
}
})
}}>
@@ -90,6 +92,8 @@ export default function Home() {
)}
+
Repo: {context.state.sharedData.tizenBrewRepo}
+ {installedVersion && Installed: {installedVersion}
}
- {
loc.route('/ui/dist/index.html/install-from-usb');
diff --git a/client/ui/src/pages/InstallFromGitHub.jsx b/client/ui/src/pages/InstallFromGitHub.jsx
index 935b186..56d0bb9 100644
--- a/client/ui/src/pages/InstallFromGitHub.jsx
+++ b/client/ui/src/pages/InstallFromGitHub.jsx
@@ -7,9 +7,9 @@ import { Events } from '../components/WebSocketClient.js';
import Item from "../components/Item.jsx";
export default function InstallFromGitHub() {
- const [name, setName] = useState('');
+ const { state, dispatch } = useContext(GlobalStateContext);
+ const [name, setName] = useState(state.sharedData.tizenBrewRepo || '');
const loc = useLocation();
- const { state } = useContext(GlobalStateContext);
const ref = useRef(null);
useEffect(() => {
@@ -20,22 +20,28 @@ export default function InstallFromGitHub() {
-
setName(e.target.value)}
onKeyDown={(e) => {
+ if (e.keyCode === 37 || e.keyCode === 39) { e.stopPropagation(); return; }
if (e.keyCode === 13 || e.keyCode === 65376) {
ref.current.blur();
}
}}
- onBlur={(e) => {
- if (name) {
+ onBlur={() => {
+ const repo = name.trim();
+ if (repo) {
+ dispatch({
+ type: 'SET_TIZENBREW_REPO',
+ payload: repo
+ });
state.client.send({
type: Events.InstallPackage,
payload: {
- url: name
+ url: repo
}
});
}
@@ -43,7 +49,7 @@ export default function InstallFromGitHub() {
loc.route('/ui/dist/index.html');
setFocus('sn:focusable-item-1');
}}
- placeholder="reisxd/TizenBrew"
+ placeholder="owner/repo"
/>