Initial scaffold for Aether Native V3 Electron Launcher
@@ -1,8 +0,0 @@
|
||||
git clone https://scott_idem@bitbucket.org/oneskyit/one-sky-it-app-native.git ~/OSIT_dev/aether_app_native
|
||||
|
||||
cd ~/OSIT_dev/aether_app_native/
|
||||
npm update
|
||||
npm start
|
||||
|
||||
git branch
|
||||
git checkout development
|
||||
@@ -1,73 +0,0 @@
|
||||
{
|
||||
"developer_tools": false,
|
||||
"native_app_which_html": "default",
|
||||
"native_app_index_path": "[home]/OSIT/native_app/app/index.html",
|
||||
"native_app_index_url": "https://app.oneskyit.com/native/index.html",
|
||||
|
||||
"native_app_js_css_base_url": "https://demo.oneskyit.com",
|
||||
"native_app_js_css_base_url_bak": "https://bak-demo.oneskyit.com",
|
||||
|
||||
"account_id": "",
|
||||
"event_id": "",
|
||||
"event_device_id": "soon_to_be_required",
|
||||
"event_location_id": "",
|
||||
"event_session_id": "",
|
||||
|
||||
"account_code": "",
|
||||
"event_code": "",
|
||||
"event_device_code": "eventually_use_code",
|
||||
"event_location_code": "",
|
||||
"event_session_code": "",
|
||||
|
||||
"app_root_path": "[home]/OSIT/native_app",
|
||||
|
||||
"api_protocol": "https",
|
||||
"api_server": "api.oneskyit.com",
|
||||
"api_port": 443,
|
||||
"api_path": "",
|
||||
"api_secret_key": "ABCD1234XYZ",
|
||||
|
||||
"api_protocol_backup": "https",
|
||||
"api_server_backup": "bak-api.oneskyit.com",
|
||||
"api_port_backup": 443,
|
||||
"api_path_backup": "",
|
||||
"api_secret_key_backup": "ABCD1234XYZ",
|
||||
|
||||
"access_control_allow_origin": "*",
|
||||
|
||||
"idb_name": "osit",
|
||||
|
||||
"local_file_cache_path": "[home]/OSIT/file_cache",
|
||||
"host_file_temp_path": "[home]/OSIT/temp",
|
||||
|
||||
|
||||
|
||||
"display_arrangement": "mirror_and_extend",
|
||||
"display_builtin_resolution": "",
|
||||
"display_builtin_refresh": "",
|
||||
"display_builtin_rotation": "",
|
||||
"display_external_resolution": "",
|
||||
"display_external_refresh": "",
|
||||
"display_external_rotation": "",
|
||||
|
||||
"audio_out_volume": null,
|
||||
"audio_in_volume": null,
|
||||
|
||||
"recording_fps": 30,
|
||||
"recording_show_cursor": true,
|
||||
"recording_highlight_clicks": false,
|
||||
"recording_screen_id": null,
|
||||
"recording_audio_device_id": null,
|
||||
"known_builtin_screen_ids": [69732032, 69733952, 69733248],
|
||||
"known_builtin_audio_device_ids": [ "AppleHDAEngineInput:1B,0,1,0:1", "BuiltInMicrophoneDevice" ],
|
||||
"recording_video_codec": "h264",
|
||||
"recording_path": "[home]/recordings",
|
||||
"recording_base_filename": "recording",
|
||||
"aperture_bin_path": null,
|
||||
"recording_start_datetime": "2019-10-12 01:01:01Z",
|
||||
"recording_stop_datetime": "2019-10-31 23:59:59Z",
|
||||
"recordings_datetime": [
|
||||
{ "start": "2019-10-11T09:50:00.00", "stop": "2019-10-11T10:15:00.00" },
|
||||
{ "start": "2019-10-11T10:50:00.00", "stop": "2019-10-11T11:15:00.00" }
|
||||
]
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "."
|
||||
}
|
||||
],
|
||||
"settings": {}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
body {
|
||||
/* min-height: 100%;
|
||||
height: 100%;
|
||||
max-height: 100%; */
|
||||
|
||||
/* margin: .1em;
|
||||
padding: .1em; */
|
||||
}
|
||||
|
||||
section#Main-Body {
|
||||
/* outline: solid thin red; */
|
||||
|
||||
/* min-height: 100%;
|
||||
height: 100%;
|
||||
max-height: 100%; */
|
||||
}
|
||||
|
||||
section#Main-Nav-Menu {
|
||||
/* min-height: 100%;
|
||||
height: 100%;
|
||||
max-height: 100%; */
|
||||
}
|
||||
|
||||
section#Main-Content {
|
||||
/* min-height: 100%;
|
||||
height: 100%;
|
||||
max-height: 100%; */
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
launcher reset
|
||||
@@ -1 +0,0 @@
|
||||
test txt
|
||||
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 7.3 KiB |
|
Before Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 17 KiB |
@@ -1,47 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
<title>One Sky IT's Aether App - External XXX</title>
|
||||
|
||||
<link rel="shortcut icon" type="image/png" href="img/favicon.ico">
|
||||
|
||||
<!-- Cascading Style Sheets (CSS) start -->
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wght@0,400;0,700;1,400;1,700&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" integrity="sha512-1ycn6IcaQQ40/MKBW2W4Rhis/DbILU74C1vSrLJxCq57o941Ym01SwNsOMqvEBFlcgUa6xLiPY/NS5R+E6ztJQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||
<!-- Cascading Style Sheets (CSS) end -->
|
||||
|
||||
<!-- JavaScript (JS) start -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.1.3/axios.min.js" integrity="sha512-0qU9M9jfqPw6FKkPafM3gy2CBAvUWnYVOfNPDYKVuRTel1PrciTj+a9P3loJB+j0QmN2Y0JYQmkBBS8W+mbezg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.2.0/socket.io.js" integrity="sha512-WL6WGKMPBiM9PnHRYIn5YEtq0Z8XP4fkVb4qy7PP4vhmYQErJ/dySyXuFIMDf1eEYCXCrQrMJfkNwKc9gsjTjA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.10.7/dayjs.min.js" integrity="sha512-bwD3VD/j6ypSSnyjuaURidZksoVx3L1RPvTkleC48SbHCZsemT3VKMD39KknPnH728LLXVMTisESIBOAb5/W0Q==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/localforage/1.10.0/localforage.min.js" integrity="sha512-+BMamP0e7wn39JGL8nKAZ3yAQT2dL5oaXWr4ZYlTGkKOaoXM/Yj7c4oy50Ngz5yoUutAG17flueD4F6QpTlPng==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
<!-- JavaScript (JS) end -->
|
||||
|
||||
<script type="module">
|
||||
import {check_and_copy_app_files} from 'https://dev-cmsc.oneskyit.com/srv/assets/js/init_bootstrap_app.js';
|
||||
check_and_copy_app_files({overwrite: true});
|
||||
</script>
|
||||
|
||||
<script src="script.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="style.css">
|
||||
|
||||
<style>
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body id="Body-Container" class="body_container">
|
||||
|
||||
Loaded HTML
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,362 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
<title>One Sky IT's Aether App - External</title>
|
||||
|
||||
<link rel="shortcut icon" type="image/png" href="img/favicon.ico">
|
||||
|
||||
<!-- Cascading Style Sheets (CSS) start -->
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wght@0,400;0,700;1,400;1,700&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" integrity="sha512-1ycn6IcaQQ40/MKBW2W4Rhis/DbILU74C1vSrLJxCq57o941Ym01SwNsOMqvEBFlcgUa6xLiPY/NS5R+E6ztJQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||
<!-- Cascading Style Sheets (CSS) end -->
|
||||
|
||||
<!-- JavaScript (JS) start -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.1.3/axios.min.js" integrity="sha512-0qU9M9jfqPw6FKkPafM3gy2CBAvUWnYVOfNPDYKVuRTel1PrciTj+a9P3loJB+j0QmN2Y0JYQmkBBS8W+mbezg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.2.0/socket.io.js" integrity="sha512-WL6WGKMPBiM9PnHRYIn5YEtq0Z8XP4fkVb4qy7PP4vhmYQErJ/dySyXuFIMDf1eEYCXCrQrMJfkNwKc9gsjTjA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.10.7/dayjs.min.js" integrity="sha512-bwD3VD/j6ypSSnyjuaURidZksoVx3L1RPvTkleC48SbHCZsemT3VKMD39KknPnH728LLXVMTisESIBOAb5/W0Q==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/localforage/1.10.0/localforage.min.js" integrity="sha512-+BMamP0e7wn39JGL8nKAZ3yAQT2dL5oaXWr4ZYlTGkKOaoXM/Yj7c4oy50Ngz5yoUutAG17flueD4F6QpTlPng==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
<!-- JavaScript (JS) end -->
|
||||
|
||||
<script type="module">
|
||||
import {check_for_native_app_update, check_and_copy_app_files, check_and_get_updated_native_app_config} from 'https://dev-cmsc.oneskyit.com/srv/assets/js/init_bootstrap_app.js';
|
||||
|
||||
check_for_native_app_update({overwrite: false});
|
||||
|
||||
check_and_copy_app_files({overwrite: true});
|
||||
|
||||
check_and_get_updated_native_app_config({overwrite: false})
|
||||
|
||||
|
||||
// let native_app_config = load_init_config();
|
||||
// console.log('Native App Initial Config:', native_app_config);
|
||||
|
||||
// const native_app = require('./script');
|
||||
// let native_app_config = native_app.load_init_config();
|
||||
// console.log('Native App Initial Config:', native_app_config);
|
||||
//
|
||||
// let native_app_js_css_base_url = native_app_config.native_app_js_css_base_url;
|
||||
//
|
||||
// document.aether = {
|
||||
// name: 'Aether Native App (Electron and Svelte)'
|
||||
// };
|
||||
|
||||
// document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/css/ae_css_variables.css" />`);
|
||||
</script>
|
||||
|
||||
<script>
|
||||
const native_app = require('./script');
|
||||
let native_app_config = native_app.load_init_config();
|
||||
console.log('Native App Initial Config:', native_app_config);
|
||||
|
||||
// native_app_config = native_app.load_full_config(native_app_config);
|
||||
// console.log('Native App Full Config:', native_app_config);
|
||||
|
||||
let native_app_js_css_base_url = native_app_config.native_app_js_css_base_url;
|
||||
|
||||
document.aether = {
|
||||
name: 'Aether Native App (Electron and Svelte)'
|
||||
};
|
||||
|
||||
function is_online(uri) {
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open('GET',uri,false);
|
||||
try {
|
||||
xhr.send(null);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
if(xhr.status == 200) {
|
||||
//is online
|
||||
return xhr.responseText;
|
||||
}
|
||||
else {
|
||||
//is offline
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_online(native_app_config.native_app_js_css_base_url)) {
|
||||
console.log(`Appears to be live: ${native_app_config.native_app_js_css_base_url}`);
|
||||
} else if (native_app_config.native_app_js_css_base_url_bak) {
|
||||
console.log(`Appears to be live: ${native_app_config.native_app_js_css_base_url_bak}`);
|
||||
native_app_js_css_base_url = native_app_config.native_app_js_css_base_url_bak;
|
||||
} else if (is_online('https://app.oneskyit.com')) {
|
||||
console.log(`Appears to be live: https://app.oneskyit.com`);
|
||||
native_app_js_css_base_url = 'https://app.oneskyit.com';
|
||||
} else if (is_online('https://oneskyit.com')) {
|
||||
console.log(`One Sky IT appears to be online`);
|
||||
native_app_js_css_base_url = 'https://oneskyit.com';
|
||||
} else if (is_online('https://google.com')) {
|
||||
console.log(`Google appears to be online`);
|
||||
native_app_js_css_base_url = 'https://google.com';
|
||||
} else {
|
||||
console.log('We are offline!');
|
||||
}
|
||||
|
||||
// console.log(`One Sky IT appears to be online ${is_online('https://oneskyit.com')}`);
|
||||
// console.log(`Google appears to be online ${is_online('https://google.com')}`);
|
||||
|
||||
// console.log(is_online('https://oneskyit.com'));
|
||||
// console.log(is_online('https://cmsc.oneskyit.com'));
|
||||
// console.log(is_online('https://dev-cmsc.oneskyit.com'));
|
||||
// console.log(is_online('https://google.com'));
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<!-- One Sky IT Cascading Style Sheets (CSS) -->
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/css/ae_css_variables.css" />`);</script>
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/css/ae_utilities.css" />`);</script>
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/css/ae_shared_components.css" />`);</script>
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/css/ae_core_modules_components.css" />`);</script>
|
||||
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/css/ae_layout_base.css" />`);</script>
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/css/ae_layout_system.css" />`);</script>
|
||||
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/ae_app_core_bundle.css" />`);</script>
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/ae_app_mods_bundle.css" />`);</script>
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/ae_app_mod_events_bundle.css" />`);</script>
|
||||
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/css/ae_temp.css" />`);</script>
|
||||
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/css/event.css" />`);</script>
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/css/event_launcher.css" />`);</script>
|
||||
|
||||
<link rel="stylesheet" href="style.css">
|
||||
|
||||
<style>
|
||||
</style>
|
||||
|
||||
|
||||
<script>
|
||||
// BEGIN: Environment constants set by server when rendering HTML
|
||||
// Environment options: development_local, development_remote, production_local, production_remote,
|
||||
// END: Environment constants set by server when rendering HTML
|
||||
|
||||
// BEGIN: Content constants set by server when rendering HTML
|
||||
// const page_for_id = {"event": native_app_config.event_id, "event_device": native_app_config.event_device_id, "event_location": native_app_config.event_location_id, "event_session": native_app_config.event_session_id}; // Simple key value like object
|
||||
const page_for = {'event_id': native_app_config.event_id, 'event_device_id': native_app_config.event_device_id, 'event_location_id': native_app_config.event_location_id, 'event_session_id': native_app_config.event_session_id}; // Simple key value like object
|
||||
console.log('Page For:', page_for);
|
||||
// END: Content constants set by server when rendering HTML
|
||||
|
||||
// BEGIN: Client constants set by server when rendering HTML
|
||||
const client_account_jwt = {}; // Future use
|
||||
const client_person_jwt = {}; // Future use
|
||||
const client_user_jwt = {}; // Future use
|
||||
|
||||
let client_account_id = native_app_config.account_id;
|
||||
// console.log(client_account_id);
|
||||
|
||||
// END: Client constants set by server when rendering HTML
|
||||
|
||||
// BEGIN: Other constants set by server when rendering HTML
|
||||
// END: Other constants set by server when rendering HTML
|
||||
|
||||
|
||||
document.aether.cfg = {};
|
||||
document.aether.cfg.app = { "name": "One Sky IT's Aether Native App DEV", "version": "3.5 DEV", "email": null, "env": null, "mode": "native", "local_file_cache_path": native_app_config.local_file_cache_path, "host_file_temp_path": native_app_config.host_file_temp_path };
|
||||
document.aether.cfg.api = { "protocol": native_app_config.api_protocol, "server": native_app_config.api_server, "port": native_app_config.api_port, "path": native_app_config.api_path, "secret_key": native_app_config.api_secret_key, "base_url": null, "temporary_token": {"token": null, "expire_on": null}, "protocol_backup": native_app_config.api_protocol_backup, "server_backup": native_app_config.api_server_backup, "port_backup": native_app_config.api_port_backup, "path_backup": native_app_config.api_path_backup, "secret_key_backup": native_app_config.api_secret_key_backup, "base_url_backup": null, "temporary_token_backup": {"token": null, "expire_on": null} };
|
||||
document.aether.cfg.idb = { "name": native_app_config.idb_name };
|
||||
|
||||
|
||||
document.aether.client = { "account_id": native_app_config.account_id, "site_id": native_app_config.site_id, "site_domain_id": native_app_config.site_domain_id, "person_id": null, "user_id": null, "order_cart_id_random": null, "super_check": false, "manager_check": false, "administrator_check": false, "support_check": false, "assistant_check": false, "trusted_check": false, "verified_check": false, "provisional_check": false, "public_check": false, "user_check": false, "logged_in_check": false, "person_check": false, "authenticated_check": false, "anonymous_check": true, "person_group": null, "user_group": null, "orders_closed_count": 0, "order_count": 0, "app_mode": "native", "administrator_passcode": "11500", "trusted_passcode": "19111", "authenticated_passcode": "20902" };
|
||||
|
||||
|
||||
let page = {}
|
||||
page['mode'] = null;
|
||||
// page['page_for_id'] = { 'event': native_app_config.event_id, 'event_device': native_app_config.event_device_id, 'event_location': native_app_config.event_location_id, 'event_session': native_app_config.event_session_id }; // Simple key value like object;
|
||||
page['page_for'] = { 'event_id': native_app_config.event_id, 'event_device_id': native_app_config.event_device_id, 'event_location_id': native_app_config.event_location_id, 'event_session_id': native_app_config.event_session_id }; // Simple key value like object;
|
||||
|
||||
page['current_url_root'] = null;
|
||||
page['current_url_full_path'] = null;
|
||||
|
||||
page['data'] = null; // Pre-populate the page data from the rendering server (Electron app).
|
||||
page['mode'] = null; // For future use or in other contexts
|
||||
page['params'] = null; // For future use or in other contexts
|
||||
|
||||
document.aether.page = page;
|
||||
|
||||
|
||||
let aether = JSON.stringify(document.aether);
|
||||
let aether_cfg = JSON.stringify(document.aether.cfg);
|
||||
let aether_client = JSON.stringify(document.aether.client);
|
||||
let aether_page = JSON.stringify(document.aether.page);
|
||||
|
||||
localStorage.setItem('ae_cfg', aether_cfg);
|
||||
sessionStorage.setItem('ae', aether);
|
||||
sessionStorage.setItem('ae_client', aether_client);
|
||||
sessionStorage.setItem('ae_page', aether_page);
|
||||
|
||||
/* ***** **** *** ** * ### * ** *** **** ***** */
|
||||
|
||||
let app_online = false;
|
||||
//let app_use_cached_data = true;
|
||||
window.addEventListener('online', native_app.currently_online);
|
||||
window.addEventListener('offline', native_app.currently_offline);
|
||||
|
||||
/* ***** **** *** ** * ### * ** *** **** ***** */
|
||||
|
||||
const ae_bridge = {
|
||||
example_var: 'Example Default Value',
|
||||
get example() {
|
||||
return this.example_var;
|
||||
},
|
||||
set example(new_value) {
|
||||
this.example_var = new_value;
|
||||
this.example_var_listener(new_value);
|
||||
this.example_var_core_listener(new_value);
|
||||
this.example_var_mods_listener(new_value);
|
||||
},
|
||||
|
||||
example_var_listener: function (new_value) {},
|
||||
registerNewListener: function (external_listener_function) {
|
||||
this.example_var_listener = external_listener_function;
|
||||
},
|
||||
|
||||
example_var_core_listener: function (new_value) {},
|
||||
registerNewCoreListener: function (external_core_listener_function) {
|
||||
this.example_var_core_listener = external_core_listener_function;
|
||||
},
|
||||
|
||||
example_var_mods_listener: function (new_value) {},
|
||||
registerNewModsListener: function (external_mods_listener_function) {
|
||||
this.example_var_mods_listener = external_mods_listener_function;
|
||||
},
|
||||
|
||||
// Monitor change in Access Type
|
||||
access_type_var: 'anonymous',
|
||||
get access_type() {
|
||||
return this.access_type_var;
|
||||
},
|
||||
set access_type(new_value) {
|
||||
this.access_type_var = new_value;
|
||||
this.access_type_var_core_listener(new_value);
|
||||
this.access_type_var_mods_listener(new_value);
|
||||
},
|
||||
|
||||
access_type_var_core_listener: function (new_value) {},
|
||||
register_core_access_type_listener: function (external_core_listener_function) {
|
||||
this.access_type_var_core_listener = external_core_listener_function;
|
||||
},
|
||||
|
||||
access_type_var_mods_listener: function (new_value) {},
|
||||
register_mods_access_type_listener: function (external_mods_listener_function) {
|
||||
this.access_type_var_mods_listener = external_mods_listener_function;
|
||||
},
|
||||
|
||||
|
||||
// Monitor change in AE Common
|
||||
ae_com_var: 'anonymous',
|
||||
get ae_com() {
|
||||
return this.ae_com_var;
|
||||
},
|
||||
set ae_com(new_value) {
|
||||
this.ae_com_var = new_value;
|
||||
this.ae_com_var_core_listener(new_value);
|
||||
this.ae_com_var_mods_listener(new_value);
|
||||
},
|
||||
|
||||
ae_com_var_core_listener: function (new_value) {},
|
||||
register_core_ae_com_listener: function (external_core_listener_function) {
|
||||
this.ae_com_var_core_listener = external_core_listener_function;
|
||||
},
|
||||
|
||||
ae_com_var_mods_listener: function (new_value) {},
|
||||
register_mods_ae_com_listener: function (external_mods_listener_function) {
|
||||
this.ae_com_var_mods_listener = external_mods_listener_function;
|
||||
},
|
||||
|
||||
|
||||
// Monitor change in Client
|
||||
client_var: 'anonymous',
|
||||
get client() {
|
||||
return this.client_var;
|
||||
},
|
||||
set client(new_value) {
|
||||
this.client_var = new_value;
|
||||
this.client_var_core_listener(new_value);
|
||||
this.client_var_mods_listener(new_value);
|
||||
},
|
||||
|
||||
client_var_core_listener: function (new_value) {},
|
||||
register_core_client_listener: function (external_core_listener_function) {
|
||||
this.client_var_core_listener = external_core_listener_function;
|
||||
},
|
||||
|
||||
client_var_mods_listener: function (new_value) {},
|
||||
register_mods_client_listener: function (external_mods_listener_function) {
|
||||
this.client_var_mods_listener = external_mods_listener_function;
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
/* ***** **** *** ** * ### * ** *** **** ***** */
|
||||
|
||||
let svelte_ae_app_core_bundle_js = document.createElement('script');
|
||||
svelte_ae_app_core_bundle_js.setAttribute('src', `${native_app_js_css_base_url}/static/ae_app_core_bundle.js`);
|
||||
document.head.appendChild(svelte_ae_app_core_bundle_js);
|
||||
|
||||
let svelte_ae_app_mods_bundle_js = document.createElement('script');
|
||||
svelte_ae_app_mods_bundle_js.setAttribute('src', `${native_app_js_css_base_url}/static/ae_app_mods_bundle.js`);
|
||||
document.head.appendChild(svelte_ae_app_mods_bundle_js);
|
||||
|
||||
let svelte_ae_app_mod_events_bundle_js = document.createElement('script');
|
||||
svelte_ae_app_mod_events_bundle_js.setAttribute('src', `${native_app_js_css_base_url}/static/ae_app_mod_events_bundle.js`);
|
||||
document.head.appendChild(svelte_ae_app_mod_events_bundle_js);
|
||||
</script>
|
||||
|
||||
<!-- <script>document.write(`<script src="${native_app_js_css_base_url}/static/svelte/build/bundle.js" crossorigin />`);</script> -->
|
||||
|
||||
<!-- JavaScript (JS) end -->
|
||||
</head>
|
||||
|
||||
<body id="Body-Container" class="body_container">
|
||||
|
||||
<section id="System-Nav-Menu">Site-Nav-Menu</section>
|
||||
|
||||
<div id="Site-Container">
|
||||
|
||||
<section id="Site-Header">Site-Header</section>
|
||||
|
||||
<nav id="Site-Nav-Menu">Site-Nav-Menu</nav>
|
||||
|
||||
<section id="Notifications">
|
||||
<section id="System-Notifications">System-Notifications (and Site-Notifications)</section><!-- and what would be Site-Notifications-->
|
||||
|
||||
</section>
|
||||
|
||||
<section id="Main-Body" class="main_template_content svelte_target event_launcher_main Side-Main-Nav-Menu">
|
||||
<section id="Main-Nav-Menu"></section>
|
||||
<main id="Main-Content"></main>
|
||||
</section>
|
||||
<section id="Site-Set-Access-Type" class="svelte_target set_access_type"></section>
|
||||
|
||||
<section id="Site-Footer">Site-Footer</section>
|
||||
|
||||
</div>
|
||||
|
||||
<section id="Site-Modals"></section>
|
||||
|
||||
<section id="System-Footer">Site-Footer</section>
|
||||
|
||||
<section id="System-Debug">System-Debug</section>
|
||||
|
||||
</body>
|
||||
<!-- JavaScript (JS) start -->
|
||||
<!-- <script>const app = require('./js/app_v3');</script> -->
|
||||
<!-- <script src="js/app_v3.js"></script> -->
|
||||
<script>
|
||||
/* ***** **** *** ** * ### * ** *** **** ***** */
|
||||
/* ***** **** *** ** * ### * ** *** **** ***** */
|
||||
</script>
|
||||
<!-- JavaScript (JS) end -->
|
||||
|
||||
|
||||
</html>
|
||||
279
app/index.html
@@ -1,279 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
<title>One Sky IT's Aether App</title>
|
||||
|
||||
<link rel="shortcut icon" type="image/png" href="img/favicon.ico">
|
||||
|
||||
<!-- Cascading Style Sheets (CSS) start -->
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wght@0,400;0,700;1,400;1,700&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" integrity="sha512-1ycn6IcaQQ40/MKBW2W4Rhis/DbILU74C1vSrLJxCq57o941Ym01SwNsOMqvEBFlcgUa6xLiPY/NS5R+E6ztJQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||
<!-- Cascading Style Sheets (CSS) end -->
|
||||
|
||||
<!-- JavaScript (JS) start -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.1.3/axios.min.js" integrity="sha512-0qU9M9jfqPw6FKkPafM3gy2CBAvUWnYVOfNPDYKVuRTel1PrciTj+a9P3loJB+j0QmN2Y0JYQmkBBS8W+mbezg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.2.0/socket.io.js" integrity="sha512-WL6WGKMPBiM9PnHRYIn5YEtq0Z8XP4fkVb4qy7PP4vhmYQErJ/dySyXuFIMDf1eEYCXCrQrMJfkNwKc9gsjTjA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.10.7/dayjs.min.js" integrity="sha512-bwD3VD/j6ypSSnyjuaURidZksoVx3L1RPvTkleC48SbHCZsemT3VKMD39KknPnH728LLXVMTisESIBOAb5/W0Q==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/localforage/1.10.0/localforage.min.js" integrity="sha512-+BMamP0e7wn39JGL8nKAZ3yAQT2dL5oaXWr4ZYlTGkKOaoXM/Yj7c4oy50Ngz5yoUutAG17flueD4F6QpTlPng==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
<!-- JavaScript (JS) end -->
|
||||
|
||||
<script>
|
||||
const native_app = require('./js/aether_app_native_v4');
|
||||
let native_app_config = native_app.load_init_config();
|
||||
console.log('Native App Initial Config:', native_app_config);
|
||||
|
||||
// native_app_config = native_app.load_full_config(native_app_config);
|
||||
// console.log('Native App Full Config:', native_app_config);
|
||||
|
||||
let native_app_js_css_base_url = native_app_config.native_app_js_css_base_url;
|
||||
|
||||
document.aether = {
|
||||
name: 'Aether Native App (Electron and Svelte)'
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<!-- One Sky IT Cascading Style Sheets (CSS) -->
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/css/ae_css_variables.css" />`);</script>
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/css/ae_utilities.css" />`);</script>
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/css/ae_shared_components.css" />`);</script>
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/css/ae_core_modules_components.css" />`);</script>
|
||||
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/css/ae_layout_base.css" />`);</script>
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/css/ae_layout_system.css" />`);</script>
|
||||
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/ae_app_core_bundle.css" />`);</script>
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/ae_app_mods_bundle.css" />`);</script>
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/ae_app_mod_events_bundle.css" />`);</script>
|
||||
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/css/ae_temp.css" />`);</script>
|
||||
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/css/event.css" />`);</script>
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/css/event_launcher.css" />`);</script>
|
||||
|
||||
<link rel="stylesheet" href="css/aether_app_native_v3.css">
|
||||
|
||||
<style>
|
||||
</style>
|
||||
|
||||
|
||||
<script>
|
||||
// BEGIN: Environment constants set by server when rendering HTML
|
||||
// Environment options: development_local, development_remote, production_local, production_remote,
|
||||
// END: Environment constants set by server when rendering HTML
|
||||
|
||||
// BEGIN: Content constants set by server when rendering HTML
|
||||
// const page_for_id = {"event": native_app_config.event_id, "event_device": native_app_config.event_device_id, "event_location": native_app_config.event_location_id, "event_session": native_app_config.event_session_id}; // Simple key value like object
|
||||
const page_for = {'event_id': native_app_config.event_id, 'event_device_id': native_app_config.event_device_id, 'event_location_id': native_app_config.event_location_id, 'event_session_id': native_app_config.event_session_id}; // Simple key value like object
|
||||
console.log('Page For:', page_for);
|
||||
// END: Content constants set by server when rendering HTML
|
||||
|
||||
// BEGIN: Client constants set by server when rendering HTML
|
||||
const client_account_jwt = {}; // Future use
|
||||
const client_person_jwt = {}; // Future use
|
||||
const client_user_jwt = {}; // Future use
|
||||
|
||||
let client_account_id = native_app_config.account_id;
|
||||
console.log(client_account_id);
|
||||
|
||||
// END: Client constants set by server when rendering HTML
|
||||
|
||||
// BEGIN: Other constants set by server when rendering HTML
|
||||
// END: Other constants set by server when rendering HTML
|
||||
|
||||
|
||||
document.aether.cfg = {};
|
||||
document.aether.cfg.app = { "name": "One Sky IT's Aether Native App DEV", "version": "3.5 DEV", "email": null, "env": null, "mode": "native", "local_file_cache_path": native_app_config.local_file_cache_path, "host_file_temp_path": native_app_config.host_file_temp_path };
|
||||
document.aether.cfg.api = { "protocol": native_app_config.api_protocol, "server": native_app_config.api_server, "port": native_app_config.api_port, "path": native_app_config.api_path, "secret_key": native_app_config.api_secret_key, "base_url": null, "temporary_token": {"token": null, "expire_on": null}, "protocol_backup": native_app_config.api_protocol_backup, "server_backup": native_app_config.api_server_backup, "port_backup": native_app_config.api_port_backup, "path_backup": native_app_config.api_path_backup, "secret_key_backup": native_app_config.api_secret_key_backup, "base_url_backup": null, "temporary_token_backup": {"token": null, "expire_on": null} };
|
||||
document.aether.cfg.idb = { "name": native_app_config.idb_name };
|
||||
|
||||
|
||||
document.aether.client = { "account_id": native_app_config.account_id, "site_id": native_app_config.site_id, "site_domain_id": native_app_config.site_domain_id, "person_id": null, "user_id": null, "order_cart_id_random": null, "super_check": false, "manager_check": false, "administrator_check": false, "support_check": false, "assistant_check": false, "trusted_check": false, "verified_check": false, "provisional_check": false, "public_check": false, "user_check": false, "logged_in_check": false, "person_check": false, "authenticated_check": false, "anonymous_check": true, "person_group": null, "user_group": null, "orders_closed_count": 0, "order_count": 0, "app_mode": "native" };
|
||||
|
||||
|
||||
let page = {}
|
||||
page['mode'] = null;
|
||||
// page['page_for_id'] = { 'event': native_app_config.event_id, 'event_device': native_app_config.event_device_id, 'event_location': native_app_config.event_location_id, 'event_session': native_app_config.event_session_id }; // Simple key value like object;
|
||||
page['page_for'] = { 'event_id': native_app_config.event_id, 'event_device_id': native_app_config.event_device_id, 'event_location_id': native_app_config.event_location_id, 'event_session_id': native_app_config.event_session_id }; // Simple key value like object;
|
||||
|
||||
page['current_url_root'] = null;
|
||||
page['current_url_full_path'] = null;
|
||||
|
||||
page['data'] = null; // Pre-populate the page data from the rendering server (Electron app).
|
||||
page['mode'] = null; // For future use or in other contexts
|
||||
page['params'] = null; // For future use or in other contexts
|
||||
|
||||
document.aether.page = page;
|
||||
|
||||
/* ***** **** *** ** * ### * ** *** **** ***** */
|
||||
|
||||
let app_online = false;
|
||||
//let app_use_cached_data = true;
|
||||
window.addEventListener('online', native_app.currently_online);
|
||||
window.addEventListener('offline', native_app.currently_offline);
|
||||
|
||||
/* ***** **** *** ** * ### * ** *** **** ***** */
|
||||
|
||||
const ae_bridge = {
|
||||
example_var: 'Example Default Value',
|
||||
get example() {
|
||||
return this.example_var;
|
||||
},
|
||||
set example(new_value) {
|
||||
this.example_var = new_value;
|
||||
this.example_var_listener(new_value);
|
||||
this.example_var_core_listener(new_value);
|
||||
this.example_var_mods_listener(new_value);
|
||||
},
|
||||
|
||||
example_var_listener: function (new_value) {},
|
||||
registerNewListener: function (external_listener_function) {
|
||||
this.example_var_listener = external_listener_function;
|
||||
},
|
||||
|
||||
example_var_core_listener: function (new_value) {},
|
||||
registerNewCoreListener: function (external_core_listener_function) {
|
||||
this.example_var_core_listener = external_core_listener_function;
|
||||
},
|
||||
|
||||
example_var_mods_listener: function (new_value) {},
|
||||
registerNewModsListener: function (external_mods_listener_function) {
|
||||
this.example_var_mods_listener = external_mods_listener_function;
|
||||
},
|
||||
|
||||
// Monitor change in Access Type
|
||||
access_type_var: 'anonymous',
|
||||
get access_type() {
|
||||
return this.access_type_var;
|
||||
},
|
||||
set access_type(new_value) {
|
||||
this.access_type_var = new_value;
|
||||
this.access_type_var_core_listener(new_value);
|
||||
this.access_type_var_mods_listener(new_value);
|
||||
},
|
||||
|
||||
access_type_var_core_listener: function (new_value) {},
|
||||
register_core_access_type_listener: function (external_core_listener_function) {
|
||||
this.access_type_var_core_listener = external_core_listener_function;
|
||||
},
|
||||
|
||||
access_type_var_mods_listener: function (new_value) {},
|
||||
register_mods_access_type_listener: function (external_mods_listener_function) {
|
||||
this.access_type_var_mods_listener = external_mods_listener_function;
|
||||
},
|
||||
|
||||
|
||||
// Monitor change in AE Common
|
||||
ae_com_var: 'anonymous',
|
||||
get ae_com() {
|
||||
return this.ae_com_var;
|
||||
},
|
||||
set ae_com(new_value) {
|
||||
this.ae_com_var = new_value;
|
||||
this.ae_com_var_core_listener(new_value);
|
||||
this.ae_com_var_mods_listener(new_value);
|
||||
},
|
||||
|
||||
ae_com_var_core_listener: function (new_value) {},
|
||||
register_core_ae_com_listener: function (external_core_listener_function) {
|
||||
this.ae_com_var_core_listener = external_core_listener_function;
|
||||
},
|
||||
|
||||
ae_com_var_mods_listener: function (new_value) {},
|
||||
register_mods_ae_com_listener: function (external_mods_listener_function) {
|
||||
this.ae_com_var_mods_listener = external_mods_listener_function;
|
||||
},
|
||||
|
||||
|
||||
// Monitor change in Client
|
||||
client_var: 'anonymous',
|
||||
get client() {
|
||||
return this.client_var;
|
||||
},
|
||||
set client(new_value) {
|
||||
this.client_var = new_value;
|
||||
this.client_var_core_listener(new_value);
|
||||
this.client_var_mods_listener(new_value);
|
||||
},
|
||||
|
||||
client_var_core_listener: function (new_value) {},
|
||||
register_core_client_listener: function (external_core_listener_function) {
|
||||
this.client_var_core_listener = external_core_listener_function;
|
||||
},
|
||||
|
||||
client_var_mods_listener: function (new_value) {},
|
||||
register_mods_client_listener: function (external_mods_listener_function) {
|
||||
this.client_var_mods_listener = external_mods_listener_function;
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
/* ***** **** *** ** * ### * ** *** **** ***** */
|
||||
|
||||
let svelte_ae_app_core_bundle_js = document.createElement('script');
|
||||
svelte_ae_app_core_bundle_js.setAttribute('src', `${native_app_js_css_base_url}/static/ae_app_core_bundle.js`);
|
||||
document.head.appendChild(svelte_ae_app_core_bundle_js);
|
||||
|
||||
let svelte_ae_app_mods_bundle_js = document.createElement('script');
|
||||
svelte_ae_app_mods_bundle_js.setAttribute('src', `${native_app_js_css_base_url}/static/ae_app_mods_bundle.js`);
|
||||
document.head.appendChild(svelte_ae_app_mods_bundle_js);
|
||||
|
||||
let svelte_ae_app_mod_events_bundle_js = document.createElement('script');
|
||||
svelte_ae_app_mod_events_bundle_js.setAttribute('src', `${native_app_js_css_base_url}/static/ae_app_mod_events_bundle.js`);
|
||||
document.head.appendChild(svelte_ae_app_mod_events_bundle_js);
|
||||
</script>
|
||||
|
||||
<!-- <script>document.write(`<script src="${native_app_js_css_base_url}/static/svelte/build/bundle.js" crossorigin />`);</script> -->
|
||||
|
||||
<!-- JavaScript (JS) end -->
|
||||
</head>
|
||||
|
||||
<body id="Body-Container" class="body_container">
|
||||
|
||||
<section id="System-Nav-Menu">Site-Nav-Menu</section>
|
||||
|
||||
<div id="Site-Container">
|
||||
|
||||
<section id="Site-Header">Site-Header</section>
|
||||
|
||||
<nav id="Site-Nav-Menu">Site-Nav-Menu</nav>
|
||||
|
||||
<section id="Notifications">
|
||||
<section id="System-Notifications">System-Notifications (and Site-Notifications)</section><!-- and what would be Site-Notifications-->
|
||||
|
||||
</section>
|
||||
|
||||
<section id="Main-Body" class="main_template_content svelte_target event_launcher_main Side-Main-Nav-Menu">
|
||||
<section id="Main-Nav-Menu"></section>
|
||||
<main id="Main-Content"></main>
|
||||
</section>
|
||||
|
||||
<section id="Site-Footer">Site-Footer</section>
|
||||
|
||||
</div>
|
||||
|
||||
<section id="Site-Modals"></section>
|
||||
|
||||
<section id="System-Footer">Site-Footer</section>
|
||||
|
||||
<section id="System-Debug">System-Debug</section>
|
||||
|
||||
</body>
|
||||
<!-- JavaScript (JS) start -->
|
||||
<!-- <script>const app = require('./js/app_v3');</script> -->
|
||||
<!-- <script src="js/app_v3.js"></script> -->
|
||||
<script>
|
||||
/* ***** **** *** ** * ### * ** *** **** ***** */
|
||||
/* ***** **** *** ** * ### * ** *** **** ***** */
|
||||
</script>
|
||||
<!-- JavaScript (JS) end -->
|
||||
|
||||
|
||||
</html>
|
||||
@@ -1,632 +0,0 @@
|
||||
'use strict';
|
||||
const os = require('os');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const fs_promises = require('node:fs/promises');
|
||||
const child_process = require('child_process');
|
||||
const { ipcRenderer } = require('electron');
|
||||
|
||||
// import psList from 'ps-list';
|
||||
// const ps_list = require('ps-list');
|
||||
|
||||
let home_directory = require('os').homedir();
|
||||
console.log('Home: '+home_directory);
|
||||
|
||||
let tmp_directory = require('os').tmpdir();
|
||||
console.log('Temporary: '+tmp_directory);
|
||||
|
||||
let config = null;
|
||||
|
||||
exports.load_config = function () {
|
||||
console.log('*** Electron framework: load_config() ***');
|
||||
|
||||
let cwd = process.cwd();
|
||||
console.log(`CWD: ${cwd}`);
|
||||
|
||||
try {
|
||||
if (cwd == '/') {
|
||||
cwd = home_directory;
|
||||
}
|
||||
console.log('Reading directory...');
|
||||
let directory_list = fs_promises.readdir(cwd).then(function (read_dir_result) {
|
||||
console.log('Got contents:');
|
||||
for (let file of read_dir_result) {
|
||||
console.log(file);
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
|
||||
// let home_directory = require('os').homedir();
|
||||
// console.log('Home: '+home_directory);
|
||||
|
||||
// let tmp_directory = require('os').tmpdir();
|
||||
// console.log('Temporary: '+tmp_directory);
|
||||
|
||||
// let config = null;
|
||||
let config_directory = null;
|
||||
// let default_config_path = path.join(process.cwd(),'config.json.default');
|
||||
let default_config_path = 'config.json.default';
|
||||
console.log(default_config_path);
|
||||
let config_path = null;
|
||||
|
||||
// Set the config path for macOS or Linux
|
||||
if (os.platform == 'darwin') {
|
||||
config_directory = path.join(home_directory, 'Library/Application Support/OSIT');
|
||||
console.log('macOS config directory: '+config_directory);
|
||||
} else if (os.platform == 'linux') {
|
||||
config_directory = path.join(home_directory, '.config/OSIT');
|
||||
console.log('Linux config directory: '+config_directory);
|
||||
}
|
||||
|
||||
// Look for the config file and copy the default if not found.
|
||||
if (fs.existsSync(config_directory)) {
|
||||
console.log('Config directory found: '+config_directory);
|
||||
} else {
|
||||
fs.mkdirSync(config_directory);
|
||||
console.log('Config directory created: '+config_directory);
|
||||
|
||||
//default_config_path = path.join(process.cwd(),'config.json.default');
|
||||
// config_path = path.join(config_directory, 'config.json');
|
||||
// fs.copyFileSync(default_config_path, config_path);
|
||||
// console.log('Default config file copied: '+config_directory);
|
||||
}
|
||||
|
||||
config_path = path.join(config_directory, 'config.json');
|
||||
|
||||
// Attempt to open the config file. The preferred location is based on the OS's config directory.
|
||||
if (fs.existsSync(config_path)) {
|
||||
console.log(`Config file (config.json) found under ${config_directory}`);
|
||||
} else if (!fs.existsSync(config_path) && fs.existsSync(default_config_path)) {
|
||||
fs.copyFileSync(default_config_path, config_path);
|
||||
console.log('Default config file copied: '+config_directory);
|
||||
|
||||
// config = JSON.parse(fs.readFileSync(config_path));
|
||||
// console.log('Config file read.');
|
||||
} else if (fs.existsSync(path.join(cwd, 'config.json'))) {
|
||||
//fs.copyFileSync(default_config_path, config_path);
|
||||
//console.log('Default config file copied: '+config_directory);
|
||||
|
||||
console.log(`Config file (config.json) not found under ${config_directory}. Using config in CWD. ${cwd}`);
|
||||
config_path = path.join(cwd, 'config.json');
|
||||
|
||||
console.log(`Config file (config.json) not found under ${config_directory}. Using config in CWD. ${cwd}`);
|
||||
let found_config_path = path.join(cwd, 'config.json');
|
||||
|
||||
fs.copyFileSync(found_config_path, config_path);
|
||||
console.log(`Found config file copied: ${config_directory}`);
|
||||
} else if (fs.existsSync(path.join(cwd, 'config.json.default'))) {
|
||||
console.log(`Config file (config.json) not found under ${config_directory} or CWD. Using default config in CWD. ${cwd}`);
|
||||
default_config_path = path.join(cwd, 'config.json.default');
|
||||
|
||||
fs.copyFileSync(default_config_path, config_path);
|
||||
console.log(`Default config file copied: ${config_directory}`);
|
||||
} else {
|
||||
console.log('Can not find a config file.');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
config = JSON.parse(fs.readFileSync(config_path));
|
||||
console.log('Config file read.');
|
||||
|
||||
config.home_directory = home_directory; // From the OS platform
|
||||
config.tmp_directory = tmp_directory; // From the OS platform
|
||||
|
||||
config.app_root_path = config.app_root_path.replace('[home]', home_directory);
|
||||
config.app_root_path = config.app_root_path.replace('[tmp]', tmp_directory);
|
||||
console.log(config.app_root_path);
|
||||
|
||||
config.local_file_cache_path = config.local_file_cache_path.replace('[home]', home_directory);
|
||||
config.local_file_cache_path = config.local_file_cache_path.replace('[tmp]', tmp_directory);
|
||||
console.log(config.local_file_cache_path);
|
||||
// if (fs.existsSync(config.local_file_cache_path)) {
|
||||
// } else {
|
||||
// fs.mkdirSync(config.local_file_cache_path);
|
||||
// console.log(`Host file cache directory created: ${config.local_file_cache_path}`);
|
||||
// }
|
||||
|
||||
config.host_file_temp_path = config.host_file_temp_path.replace('[home]', home_directory);
|
||||
config.host_file_temp_path = config.host_file_temp_path.replace('[tmp]', tmp_directory);
|
||||
console.log(config.host_file_temp_path);
|
||||
// if (fs.existsSync(config.host_file_temp_path)) {
|
||||
// } else {
|
||||
// fs.mkdirSync(config.host_file_temp_path);
|
||||
// console.log(`Host file temp directory created: ${config.host_file_temp_path}`);
|
||||
// }
|
||||
|
||||
let import_config_to_ipc_result = ipcRenderer.invoke('import_config', config).then((result) => {
|
||||
console.log('IPC import config finished');
|
||||
console.log(result);
|
||||
return true;
|
||||
})
|
||||
|
||||
//console.log(config);
|
||||
return config;
|
||||
}
|
||||
|
||||
|
||||
// Check for local file
|
||||
// Updated 2022-05-06
|
||||
exports.check_local_file = async function ({local_file_path, filename}) {
|
||||
console.log('*** Electron framework export: check_local_file() ***');
|
||||
// console.log('Check for local file');
|
||||
console.log(`Local File Path: ${local_file_path}; Filename: ${filename}`);
|
||||
|
||||
let full_local_file_path = path.join(local_file_path, filename);
|
||||
console.log(full_local_file_path);
|
||||
|
||||
if (fs.existsSync(full_local_file_path)) {
|
||||
console.log(`Local file exists: ${full_local_file_path}`);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check local hash file cache
|
||||
// Used by Svelte Event Launcher
|
||||
// NOTE: Trying to replace this with something directly in the Svelte app part. 2022-10-11
|
||||
// Updated 2022-05-06
|
||||
exports.check_hash_file_cache = async function ({local_file_cache_path, hash}) {
|
||||
// console.log('*** Electron framework export: check_hash_file_cache() ***');
|
||||
// console.log('Check local hash file cache');
|
||||
console.log(`*** Electron framework export: check_hash_file_cache() *** Host File Cache Path: ${local_file_cache_path}; Hash: ${hash}`);
|
||||
|
||||
let hash_filename = `${hash}.file`;
|
||||
|
||||
let subdirectory = hash_filename.substring(0,2);
|
||||
let subdirectory_path = path.join(local_file_cache_path, subdirectory);
|
||||
if (fs.existsSync(subdirectory_path)) {
|
||||
} else {
|
||||
console.log(`Hashed file subdirectory not found in cache: ${subdirectory_path}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
let hash_file_cache_path = path.join(subdirectory_path, hash_filename);
|
||||
// console.log(hash_file_cache_path);
|
||||
|
||||
if (fs.existsSync(hash_file_cache_path)) {
|
||||
// console.log(`Hashed file exists in cache: ${hash_file_cache_path}`);
|
||||
return true;
|
||||
} else {
|
||||
console.log(`Hashed file not found in cache: ${hash_file_cache_path}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Download hash file to cache
|
||||
// Used by Svelte Event Launcher
|
||||
// Updated 2022-05-06
|
||||
exports.download_hash_file_to_cache = async function ({api_base_url, local_file_cache_path, event_file_id=null, hash=null}) {
|
||||
// console.log('*** Electron framework export: download_hash_file_to_cache() ***');
|
||||
// console.log('Download hash file to cache');
|
||||
console.log(`*** Electron framework export: download_hash_file_to_cache() *** Base URL: ${api_base_url}; Host File Cache Path: ${local_file_cache_path}; Event File ID: ${event_file_id}; Hash: ${hash}`);
|
||||
|
||||
let endpoint = `/event/file/${event_file_id}/download`;
|
||||
|
||||
let hash_filename = `${hash}.file`;
|
||||
|
||||
let subdirectory = hash_filename.substring(0,2);
|
||||
let subdirectory_path = path.join(local_file_cache_path, subdirectory);
|
||||
if (fs.existsSync(subdirectory_path)) {
|
||||
} else {
|
||||
fs.mkdirSync(subdirectory_path);
|
||||
console.log(`Subdirectory directory created: ${subdirectory_path}`);
|
||||
}
|
||||
|
||||
let hash_file_cache_path = path.join(subdirectory_path, hash_filename);
|
||||
if (fs.existsSync(hash_file_cache_path)) {
|
||||
if (check_hash) {
|
||||
const file_buffer = fs.readFileSync(hash_file_cache_path);
|
||||
const file_hash_sha256 = crypto.createHash('sha256');
|
||||
file_hash_sha256.update(file_buffer);
|
||||
|
||||
const file_hash_sha256_check = file_hash_sha256.digest('hex');S
|
||||
if (file_hash_sha256_check == hash) {
|
||||
console.log('File hash match', file_hash_sha256_check);
|
||||
return true;
|
||||
} else {
|
||||
// This should only happen if the file is actively being downloaded or it is corrupt.
|
||||
console.log('File hash does not match', file_hash_sha256_check);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// console.log(`!!!ABOUT TO CALL DOWNLOAD FILE HANDLER!!! exports.download_hash_file_to_cache(); Base URL: ${api_base_url}`);
|
||||
let download_file_result = await ipcRenderer.invoke('download_file', api_base_url, endpoint, hash_file_cache_path).then((result) => {
|
||||
if (result) {
|
||||
console.log('IPC download file process finished successfully');
|
||||
return true;
|
||||
} else if (result == null) {
|
||||
console.log('IPC Download Result (file not found?):', result);
|
||||
return null;
|
||||
} else {
|
||||
console.log('IPC Download Result (file being downloaded or something went wrong):', result);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
// console.log(`!!!DONE WITH DOWNLOAD FILE HANDLER!!! exports.download_hash_file_to_cache(); Base URL: ${api_base_url}`);
|
||||
|
||||
return download_file_result;
|
||||
}
|
||||
|
||||
|
||||
// Open cached hash file after copying to temp directory
|
||||
// Used by Svelte Event Launcher
|
||||
// NOTE: Trying to replace this with something directly in the Svelte app part. 2022-10-11
|
||||
// Updated 2022-05-06
|
||||
exports.open_hash_file_to_temp = async function ({local_file_cache_path, hash, host_file_temp_path, filename}) {
|
||||
console.log('*** Electron framework export: open_hash_file_to_temp() ***');
|
||||
// console.log('Open cached hash file after copying to temp directory');
|
||||
console.log(`Host File Cache Path: ${local_file_cache_path}; Hash: ${hash}; Host File Temp Path: ${host_file_temp_path}; Filename: ${filename}`);
|
||||
|
||||
let subdirectory = hash.substring(0,2);
|
||||
let subdirectory_path = path.join(local_file_cache_path, subdirectory);
|
||||
if (fs.existsSync(subdirectory_path)) {
|
||||
} else {
|
||||
console.log(`Hashed file subdirectory not found in cache: ${subdirectory_path}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
let open_hash_file_to_temp_result = await ipcRenderer.invoke('open_hash_file_to_temp', subdirectory_path, hash, host_file_temp_path, filename).then((result) => {
|
||||
console.log('IPC open hash file to temp finished');
|
||||
console.log(result);
|
||||
return true;
|
||||
})
|
||||
|
||||
// let result = await ipcRenderer.send('open_local_file', local_file_cache_path, hash, host_file_temp_path, filename);
|
||||
// console.log(result);
|
||||
|
||||
console.log(open_hash_file_to_temp_result);
|
||||
console.log('End: open_hash_file_to_temp()');
|
||||
if (open_hash_file_to_temp_result) {
|
||||
console.log('File opened successfully');
|
||||
return true;
|
||||
} else {
|
||||
console.log('File was not opened successfully');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Open local file
|
||||
// Used by Svelte Event Launcher
|
||||
// NOTE: Trying to replace this with something directly in the Svelte app part. 2022-10-11
|
||||
// Updated 2022-03-10
|
||||
exports.open_local_file = async function ({local_file_path, filename}) {
|
||||
console.log('*** Electron framework export: open_local_file() ***');
|
||||
// console.log('Open local file');
|
||||
console.log(`Local File Path: ${local_file_path}; Filename: ${filename}`);
|
||||
|
||||
// let full_local_file_path = path.join(local_file_path, filename);
|
||||
// console.log(full_local_file_path);
|
||||
|
||||
// if (fs.existsSync(full_local_file_path)) {
|
||||
// console.log(`Local file exists: ${full_local_file_path}`);
|
||||
// // return true;
|
||||
// } else {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
let open_local_file_result = await ipcRenderer.invoke('open_local_file', local_file_path, filename).then((result) => {
|
||||
console.log('IPC open local file finished');
|
||||
console.log(result);
|
||||
return true;
|
||||
})
|
||||
|
||||
console.log(open_local_file_result);
|
||||
console.log('End: open_local_file()');
|
||||
if (open_local_file_result) {
|
||||
console.log('File opened successfully');
|
||||
return true;
|
||||
} else {
|
||||
console.log('File was not opened successfully');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// // Check local file cache and download from server if needed.
|
||||
// // Updated 2022-03-09
|
||||
// // exports.check_file_cache = async function ({local_file_cache_path, event_file_id, hash}) {
|
||||
// exports.check_file_cache = async function ({api_base_url, local_file_cache_path, event_file_id, hash}) {
|
||||
// console.log('*** Electron framework export: check_file_cache() ***');
|
||||
// // console.log('Check local file cache and download from server if needed.');
|
||||
// console.log(`Host File Cache Path: ${local_file_cache_path}; Event File ID: ${event_file_id}; Hash: ${hash}`);
|
||||
|
||||
// // NOTE: event_file_id is the event_file.id_random or event_file.event_file_id_random
|
||||
// let hash_filename = hash+'.file';
|
||||
|
||||
// let save_path = path.join(local_file_cache_path, hash_filename);
|
||||
// console.log(save_path);
|
||||
|
||||
// if (fs.existsSync(save_path)) {
|
||||
// console.log('Hashed file cache already exists: '+save_path);
|
||||
// return true;
|
||||
// } else {
|
||||
// console.log('Hashed file not found in local cache. Downloading file: '+save_path);
|
||||
// let endpoint = `/event/file/${event_file_id}/download`;
|
||||
// let result = await ipcRenderer.send('download_file', api_base_url, endpoint, save_path); // Must download file using main node.js thread.
|
||||
// console.log(result);
|
||||
|
||||
// return new Promise((resolve, reject) => {
|
||||
// ipcRenderer.once('download_file_reply', function(event, response){
|
||||
// console.log(response);
|
||||
// return response;
|
||||
// })
|
||||
// resolve(true);
|
||||
// });
|
||||
|
||||
// // await ipcRenderer.once('download_file_reply', function(event, response){
|
||||
// // console.log(response);
|
||||
// // return response;
|
||||
// // });
|
||||
|
||||
// // result.then(function (response) {
|
||||
// // console.log('Downloaded!!!???');
|
||||
// // return true;
|
||||
// // }).catch(function (error) {
|
||||
// // console.log(error);
|
||||
// // return false;
|
||||
// // });
|
||||
|
||||
// // return result;
|
||||
|
||||
// // console.log(result);
|
||||
// // if (result) {
|
||||
// // return true;
|
||||
// // } else {
|
||||
// // return false;
|
||||
// // }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// Check local file cache and download from server if needed. Must use IPC to Main to download file. Set a Promise to wait for download_file_reply.
|
||||
// Updated 2022-03-09
|
||||
async function check_file_cache({api_base_url, local_file_cache_path, event_file_id, hash}) {
|
||||
console.log('*** Electron framework: check_file_cache() ***');
|
||||
// console.log('Check local file cache and download from server if needed.');
|
||||
console.log(`Host File Cache Path: ${local_file_cache_path}; Event File ID: ${event_file_id}; Hash: ${hash}`);
|
||||
|
||||
// NOTE: event_file_id is the event_file.id_random or event_file.event_file_id_random
|
||||
let hash_filename = hash+'.file';
|
||||
|
||||
let save_path = path.join(local_file_cache_path, hash_filename);
|
||||
console.log(save_path);
|
||||
|
||||
if (fs.existsSync(save_path)) {
|
||||
console.log('Hashed file cache already exists: '+save_path);
|
||||
return true;
|
||||
} else {
|
||||
console.log('Hashed file not found in local cache. Downloading file: '+save_path);
|
||||
let endpoint = `/event/file/${event_file_id}/download`;
|
||||
let result = await ipcRenderer.send('download_file', api_base_url, endpoint, save_path); // Must download file using main node.js thread.
|
||||
console.log(result);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
ipcRenderer.once('download_file_reply', function(event, response){
|
||||
console.log(response);
|
||||
return response;
|
||||
})
|
||||
resolve(true);
|
||||
});
|
||||
|
||||
// await ipcRenderer.once('download_file_reply', function(event, response){
|
||||
// console.log(response);
|
||||
// return response;
|
||||
// });
|
||||
|
||||
// result.then(function (response) {
|
||||
// console.log('Downloaded!!!???');
|
||||
// return true;
|
||||
// }).catch(function (error) {
|
||||
// console.log(error);
|
||||
// return false;
|
||||
// });
|
||||
|
||||
// return result;
|
||||
|
||||
// console.log(result);
|
||||
// if (result) {
|
||||
// return true;
|
||||
// } else {
|
||||
// return false;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// IPC to Main: Open local file cache if available. Copy to temp directory with given filename first.
|
||||
// Updated 2022-03-09
|
||||
async function open_local_file({local_file_cache_path, hash, host_file_temp_path, filename}) {
|
||||
console.log('*** Electron framework: open_local_file() ***');
|
||||
// console.log('Open local file cache if available. Copy to temp directory with given filename first.');
|
||||
console.log(`Host File Cache Path: ${local_file_cache_path}; Hash: ${hash}; Host File Temp Path: ${host_file_temp_path}; Filename: ${filename}`);
|
||||
|
||||
console.log(local_file_cache_path);
|
||||
console.log(hash);
|
||||
console.log(filename);
|
||||
|
||||
let result = await ipcRenderer.send('open_local_file', local_file_cache_path, hash, host_file_temp_path, filename);
|
||||
console.log(result);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// No longer needed? Not referenced as of 2022-10-11
|
||||
exports.check_file_cache_and_open_local_file = async function ({local_file_cache_path, event_file_id, hash, host_file_temp_path, filename}) {
|
||||
console.log('*** Electron framework: check_file_cache_and_open_local_file() ***');
|
||||
console.log('Checking the local file cache against the remote server and then opening the local file.');
|
||||
|
||||
let check_file_cache_result = check_file_cache({local_file_cache_path: local_file_cache_path, event_file_id: event_file_id, hash: hash});
|
||||
console.log(check_file_cache_result);
|
||||
|
||||
if (check_file_cache_result) {
|
||||
let open_local_file_result = open_local_file({local_file_cache_path: local_file_cache_path, hash: hash, host_file_temp_path: host_file_temp_path, filename: filename});
|
||||
console.log(open_local_file_result);
|
||||
|
||||
return open_local_file_result;
|
||||
}
|
||||
|
||||
ipcRenderer.once('download_file_reply', function(event, response){
|
||||
console.log(response);
|
||||
|
||||
let open_local_file_result = open_local_file({local_file_cache_path: local_file_cache_path, hash: hash, host_file_temp_path: host_file_temp_path, filename: filename});
|
||||
console.log(open_local_file_result);
|
||||
|
||||
return open_local_file_result;
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// Kill processes
|
||||
// Updated 2022-05-07
|
||||
exports.kill_processes = async function ({process_name = null}) {
|
||||
console.log('*** Electron framework export: kill_processes() ***');
|
||||
console.log(process_name); // process_name or grep pattern
|
||||
|
||||
let cmd = '';
|
||||
if (os.platform == 'darwin') {
|
||||
// cmd = `osascript -e 'quit app "${process_name}" saving no'`;
|
||||
cmd = `osascript -e 'quit application "${process_name}" saving no'`;
|
||||
} else {
|
||||
cmd = `pkill ${process_name}`;
|
||||
}
|
||||
|
||||
child_process.exec(cmd, (err, stdout, stdin) => {
|
||||
// if (err) throw err;
|
||||
if (err) console.log(err);
|
||||
console.log(stdout);
|
||||
});
|
||||
console.log(`Killed processes matching ${process_name}`);
|
||||
|
||||
if (os.platform == 'darwin') {
|
||||
if (process_name == 'Parallels:Acrobat Reader') {
|
||||
// Regular expression: (Parallels).*(Acrobat Reader)
|
||||
// This will find any process with Parallels and Acrobat Reader in the name
|
||||
cmd = `pkill -i -f '(Parallels).*(Acrobat Reader)'`;
|
||||
|
||||
child_process.exec(cmd, (err, stdout, stdin) => {
|
||||
if (err) throw err;
|
||||
console.log(stdout);
|
||||
});
|
||||
console.log('Killed Parallels Acrobat Reader process');
|
||||
}
|
||||
|
||||
if (process_name == 'Parallels:PowerPoint') {
|
||||
// Regular expression: (Parallels).*(PowerPoint)
|
||||
// This will find any process with Parallels and PowerPoint in the name
|
||||
cmd = `pkill -i -f '(Parallels).*(PowerPoint)'`;
|
||||
|
||||
child_process.exec(cmd, (err, stdout, stdin) => {
|
||||
if (err) throw err;
|
||||
console.log(stdout);
|
||||
});
|
||||
console.log('Killed Parallels PowerPoint process');
|
||||
}
|
||||
}
|
||||
|
||||
// let signal = 'SIGTERM'; // 'SIGTERM', 'SIGINT', 'SIGHUP'
|
||||
// process.kill(pid, signal);
|
||||
// process.kill(pid, 0); // Special case test if process exists
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Run raw osascript
|
||||
// Updated 2022-05-07
|
||||
exports.run_osascript = async function ({cmd=null, interactive=false, language=null, flags='h', program_file=null}) {
|
||||
console.log('*** Electron framework export: run_osascript() ***');
|
||||
console.log(cmd);
|
||||
|
||||
if (os.platform == 'darwin') {
|
||||
} else {
|
||||
console.log('Not available for this platform. macOS (darwin) only.');
|
||||
return false;
|
||||
}
|
||||
|
||||
let osascript_str = '';
|
||||
|
||||
if (Array.isArray(cmd)) {
|
||||
console.log('List of cmd strings');
|
||||
let cmds_str = '';
|
||||
for (let i = 0; i < cmd.length; i++) {
|
||||
cmds_str += `-e '${cmd[i]}'`;
|
||||
}
|
||||
osascript_str = `osascript ${cmds_str}`
|
||||
|
||||
} else if (typeof cmd === 'string') {
|
||||
console.log('Single cmd string');
|
||||
osascript_str = `osascript -e '${cmd}'`;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (language) {
|
||||
console.log(`Language: ${language}`);
|
||||
osascript_str = `${osascript_str} -l ${language}`;
|
||||
}
|
||||
|
||||
if (flags) {
|
||||
console.log(`Flags: ${flags}`);
|
||||
osascript_str = `${osascript_str} -s ${flags}`;
|
||||
}
|
||||
|
||||
console.log(`OSA Script String: ${osascript_str}`);
|
||||
child_process.exec(osascript_str, (err, stdout, stdin) => {
|
||||
if (err) throw err;
|
||||
console.log(stdout);
|
||||
console.log(stdin);
|
||||
});
|
||||
|
||||
console.log('Finished');
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Run raw command
|
||||
// Updated 2022-05-07
|
||||
exports.run_cmd = async function ({cmd=null}) {
|
||||
console.log('*** Electron framework export: run_cmd() ***');
|
||||
|
||||
console.log(`Command String: ${cmd}`);
|
||||
|
||||
child_process.exec(cmd, (err, stdout, stdin) => {
|
||||
if (err) throw err;
|
||||
console.log(stdout);
|
||||
console.log(stdin);
|
||||
});
|
||||
|
||||
console.log('Finished');
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Run raw command
|
||||
// Updated 2022-05-25
|
||||
exports.get_device_info = async function () {
|
||||
console.log('*** Electron framework export: get_device_info() ***');
|
||||
|
||||
let data = {};
|
||||
data['arch'] = os.arch();
|
||||
data['hostname'] = os.hostname();
|
||||
data['cpus'] = os.cpus();
|
||||
data['freemem'] = os.freemem();
|
||||
data['totalmem'] = os.totalmem();
|
||||
data['loadavg'] = os.loadavg();
|
||||
data['networkInterfaces'] = os.networkInterfaces();
|
||||
data['platform'] = os.platform();
|
||||
data['release'] = os.release();
|
||||
data['uptime'] = os.uptime();
|
||||
data['version'] = os.version();
|
||||
|
||||
console.log(data);
|
||||
return data;
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
body {
|
||||
/* min-height: 100%;
|
||||
height: 100%;
|
||||
max-height: 100%; */
|
||||
|
||||
/* margin: .1em;
|
||||
padding: .1em; */
|
||||
}
|
||||
|
||||
section#Main-Body {
|
||||
/* outline: solid thin red; */
|
||||
|
||||
/* min-height: 100%;
|
||||
height: 100%;
|
||||
max-height: 100%; */
|
||||
}
|
||||
|
||||
section#Main-Nav-Menu {
|
||||
/* min-height: 100%;
|
||||
height: 100%;
|
||||
max-height: 100%; */
|
||||
}
|
||||
|
||||
section#Main-Content {
|
||||
/* min-height: 100%;
|
||||
height: 100%;
|
||||
max-height: 100%; */
|
||||
}
|
||||
279
app/test.html
@@ -1,279 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
<title>One Sky IT's Aether App</title>
|
||||
|
||||
<link rel="shortcut icon" type="image/png" href="img/favicon.ico">
|
||||
|
||||
<!-- Cascading Style Sheets (CSS) start -->
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wght@0,400;0,700;1,400;1,700&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" integrity="sha512-1ycn6IcaQQ40/MKBW2W4Rhis/DbILU74C1vSrLJxCq57o941Ym01SwNsOMqvEBFlcgUa6xLiPY/NS5R+E6ztJQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||
<!-- Cascading Style Sheets (CSS) end -->
|
||||
|
||||
<!-- JavaScript (JS) start -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.1.3/axios.min.js" integrity="sha512-0qU9M9jfqPw6FKkPafM3gy2CBAvUWnYVOfNPDYKVuRTel1PrciTj+a9P3loJB+j0QmN2Y0JYQmkBBS8W+mbezg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.2.0/socket.io.js" integrity="sha512-WL6WGKMPBiM9PnHRYIn5YEtq0Z8XP4fkVb4qy7PP4vhmYQErJ/dySyXuFIMDf1eEYCXCrQrMJfkNwKc9gsjTjA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.10.7/dayjs.min.js" integrity="sha512-bwD3VD/j6ypSSnyjuaURidZksoVx3L1RPvTkleC48SbHCZsemT3VKMD39KknPnH728LLXVMTisESIBOAb5/W0Q==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/localforage/1.10.0/localforage.min.js" integrity="sha512-+BMamP0e7wn39JGL8nKAZ3yAQT2dL5oaXWr4ZYlTGkKOaoXM/Yj7c4oy50Ngz5yoUutAG17flueD4F6QpTlPng==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
<!-- JavaScript (JS) end -->
|
||||
|
||||
<script>
|
||||
const native_app = require('./js/aether_app_native_v4');
|
||||
let native_app_config = native_app.load_init_config();
|
||||
console.log('Native App Initial Config:', native_app_config);
|
||||
|
||||
// native_app_config = native_app.load_full_config(native_app_config);
|
||||
// console.log('Native App Full Config:', native_app_config);
|
||||
|
||||
let native_app_js_css_base_url = native_app_config.native_app_js_css_base_url;
|
||||
|
||||
document.aether = {
|
||||
name: 'Aether Native App (Electron and Svelte)'
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<!-- One Sky IT Cascading Style Sheets (CSS) -->
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/css/ae_css_variables.css" />`);</script>
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/css/ae_utilities.css" />`);</script>
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/css/ae_shared_components.css" />`);</script>
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/css/ae_core_modules_components.css" />`);</script>
|
||||
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/css/ae_layout_base.css" />`);</script>
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/css/ae_layout_system.css" />`);</script>
|
||||
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/ae_app_core_bundle.css" />`);</script>
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/ae_app_mods_bundle.css" />`);</script>
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/ae_app_mod_events_bundle.css" />`);</script>
|
||||
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/css/ae_temp.css" />`);</script>
|
||||
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/css/event.css" />`);</script>
|
||||
<script>document.write(`<link rel="stylesheet" href="${native_app_js_css_base_url}/static/css/event_launcher.css" />`);</script>
|
||||
|
||||
<link rel="stylesheet" href="css/aether_app_native_v3.css">
|
||||
|
||||
<style>
|
||||
</style>
|
||||
|
||||
|
||||
<script>
|
||||
// BEGIN: Environment constants set by server when rendering HTML
|
||||
// Environment options: development_local, development_remote, production_local, production_remote,
|
||||
// END: Environment constants set by server when rendering HTML
|
||||
|
||||
// BEGIN: Content constants set by server when rendering HTML
|
||||
// const page_for_id = {"event": native_app_config.event_id, "event_device": native_app_config.event_device_id, "event_location": native_app_config.event_location_id, "event_session": native_app_config.event_session_id}; // Simple key value like object
|
||||
const page_for = {'event_id': native_app_config.event_id, 'event_device_id': native_app_config.event_device_id, 'event_location_id': native_app_config.event_location_id, 'event_session_id': native_app_config.event_session_id}; // Simple key value like object
|
||||
console.log('Page For:', page_for);
|
||||
// END: Content constants set by server when rendering HTML
|
||||
|
||||
// BEGIN: Client constants set by server when rendering HTML
|
||||
const client_account_jwt = {}; // Future use
|
||||
const client_person_jwt = {}; // Future use
|
||||
const client_user_jwt = {}; // Future use
|
||||
|
||||
let client_account_id = native_app_config.account_id;
|
||||
console.log(client_account_id);
|
||||
|
||||
// END: Client constants set by server when rendering HTML
|
||||
|
||||
// BEGIN: Other constants set by server when rendering HTML
|
||||
// END: Other constants set by server when rendering HTML
|
||||
|
||||
|
||||
document.aether.cfg = {};
|
||||
document.aether.cfg.app = { "name": "One Sky IT's Aether Native App DEV", "version": "3.5 DEV", "email": null, "env": null, "mode": "native", "local_file_cache_path": native_app_config.local_file_cache_path, "host_file_temp_path": native_app_config.host_file_temp_path };
|
||||
document.aether.cfg.api = { "protocol": native_app_config.api_protocol, "server": native_app_config.api_server, "port": native_app_config.api_port, "path": native_app_config.api_path, "secret_key": native_app_config.api_secret_key, "base_url": null, "temporary_token": {"token": null, "expire_on": null}, "protocol_backup": native_app_config.api_protocol_backup, "server_backup": native_app_config.api_server_backup, "port_backup": native_app_config.api_port_backup, "path_backup": native_app_config.api_path_backup, "secret_key_backup": native_app_config.api_secret_key_backup, "base_url_backup": null, "temporary_token_backup": {"token": null, "expire_on": null} };
|
||||
document.aether.cfg.idb = { "name": native_app_config.idb_name };
|
||||
|
||||
|
||||
document.aether.client = { "account_id": native_app_config.account_id, "site_id": native_app_config.site_id, "site_domain_id": native_app_config.site_domain_id, "person_id": null, "user_id": null, "order_cart_id_random": null, "super_check": false, "manager_check": false, "administrator_check": false, "support_check": false, "assistant_check": false, "trusted_check": false, "verified_check": false, "provisional_check": false, "public_check": false, "user_check": false, "logged_in_check": false, "person_check": false, "authenticated_check": false, "anonymous_check": true, "person_group": null, "user_group": null, "orders_closed_count": 0, "order_count": 0, "app_mode": "native" };
|
||||
|
||||
|
||||
let page = {}
|
||||
page['mode'] = null;
|
||||
// page['page_for_id'] = { 'event': native_app_config.event_id, 'event_device': native_app_config.event_device_id, 'event_location': native_app_config.event_location_id, 'event_session': native_app_config.event_session_id }; // Simple key value like object;
|
||||
page['page_for'] = { 'event_id': native_app_config.event_id, 'event_device_id': native_app_config.event_device_id, 'event_location_id': native_app_config.event_location_id, 'event_session_id': native_app_config.event_session_id }; // Simple key value like object;
|
||||
|
||||
page['current_url_root'] = null;
|
||||
page['current_url_full_path'] = null;
|
||||
|
||||
page['data'] = null; // Pre-populate the page data from the rendering server (Electron app).
|
||||
page['mode'] = null; // For future use or in other contexts
|
||||
page['params'] = null; // For future use or in other contexts
|
||||
|
||||
document.aether.page = page;
|
||||
|
||||
/* ***** **** *** ** * ### * ** *** **** ***** */
|
||||
|
||||
let app_online = false;
|
||||
//let app_use_cached_data = true;
|
||||
window.addEventListener('online', native_app.currently_online);
|
||||
window.addEventListener('offline', native_app.currently_offline);
|
||||
|
||||
/* ***** **** *** ** * ### * ** *** **** ***** */
|
||||
|
||||
const ae_bridge = {
|
||||
example_var: 'Example Default Value',
|
||||
get example() {
|
||||
return this.example_var;
|
||||
},
|
||||
set example(new_value) {
|
||||
this.example_var = new_value;
|
||||
this.example_var_listener(new_value);
|
||||
this.example_var_core_listener(new_value);
|
||||
this.example_var_mods_listener(new_value);
|
||||
},
|
||||
|
||||
example_var_listener: function (new_value) {},
|
||||
registerNewListener: function (external_listener_function) {
|
||||
this.example_var_listener = external_listener_function;
|
||||
},
|
||||
|
||||
example_var_core_listener: function (new_value) {},
|
||||
registerNewCoreListener: function (external_core_listener_function) {
|
||||
this.example_var_core_listener = external_core_listener_function;
|
||||
},
|
||||
|
||||
example_var_mods_listener: function (new_value) {},
|
||||
registerNewModsListener: function (external_mods_listener_function) {
|
||||
this.example_var_mods_listener = external_mods_listener_function;
|
||||
},
|
||||
|
||||
// Monitor change in Access Type
|
||||
access_type_var: 'anonymous',
|
||||
get access_type() {
|
||||
return this.access_type_var;
|
||||
},
|
||||
set access_type(new_value) {
|
||||
this.access_type_var = new_value;
|
||||
this.access_type_var_core_listener(new_value);
|
||||
this.access_type_var_mods_listener(new_value);
|
||||
},
|
||||
|
||||
access_type_var_core_listener: function (new_value) {},
|
||||
register_core_access_type_listener: function (external_core_listener_function) {
|
||||
this.access_type_var_core_listener = external_core_listener_function;
|
||||
},
|
||||
|
||||
access_type_var_mods_listener: function (new_value) {},
|
||||
register_mods_access_type_listener: function (external_mods_listener_function) {
|
||||
this.access_type_var_mods_listener = external_mods_listener_function;
|
||||
},
|
||||
|
||||
|
||||
// Monitor change in AE Common
|
||||
ae_com_var: 'anonymous',
|
||||
get ae_com() {
|
||||
return this.ae_com_var;
|
||||
},
|
||||
set ae_com(new_value) {
|
||||
this.ae_com_var = new_value;
|
||||
this.ae_com_var_core_listener(new_value);
|
||||
this.ae_com_var_mods_listener(new_value);
|
||||
},
|
||||
|
||||
ae_com_var_core_listener: function (new_value) {},
|
||||
register_core_ae_com_listener: function (external_core_listener_function) {
|
||||
this.ae_com_var_core_listener = external_core_listener_function;
|
||||
},
|
||||
|
||||
ae_com_var_mods_listener: function (new_value) {},
|
||||
register_mods_ae_com_listener: function (external_mods_listener_function) {
|
||||
this.ae_com_var_mods_listener = external_mods_listener_function;
|
||||
},
|
||||
|
||||
|
||||
// Monitor change in Client
|
||||
client_var: 'anonymous',
|
||||
get client() {
|
||||
return this.client_var;
|
||||
},
|
||||
set client(new_value) {
|
||||
this.client_var = new_value;
|
||||
this.client_var_core_listener(new_value);
|
||||
this.client_var_mods_listener(new_value);
|
||||
},
|
||||
|
||||
client_var_core_listener: function (new_value) {},
|
||||
register_core_client_listener: function (external_core_listener_function) {
|
||||
this.client_var_core_listener = external_core_listener_function;
|
||||
},
|
||||
|
||||
client_var_mods_listener: function (new_value) {},
|
||||
register_mods_client_listener: function (external_mods_listener_function) {
|
||||
this.client_var_mods_listener = external_mods_listener_function;
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
/* ***** **** *** ** * ### * ** *** **** ***** */
|
||||
|
||||
let svelte_ae_app_core_bundle_js = document.createElement('script');
|
||||
svelte_ae_app_core_bundle_js.setAttribute('src', `${native_app_js_css_base_url}/static/ae_app_core_bundle.js`);
|
||||
document.head.appendChild(svelte_ae_app_core_bundle_js);
|
||||
|
||||
let svelte_ae_app_mods_bundle_js = document.createElement('script');
|
||||
svelte_ae_app_mods_bundle_js.setAttribute('src', `${native_app_js_css_base_url}/static/ae_app_mods_bundle.js`);
|
||||
document.head.appendChild(svelte_ae_app_mods_bundle_js);
|
||||
|
||||
let svelte_ae_app_mod_events_bundle_js = document.createElement('script');
|
||||
svelte_ae_app_mod_events_bundle_js.setAttribute('src', `${native_app_js_css_base_url}/static/ae_app_mod_events_bundle.js`);
|
||||
document.head.appendChild(svelte_ae_app_mod_events_bundle_js);
|
||||
</script>
|
||||
|
||||
<!-- <script>document.write(`<script src="${native_app_js_css_base_url}/static/svelte/build/bundle.js" crossorigin />`);</script> -->
|
||||
|
||||
<!-- JavaScript (JS) end -->
|
||||
</head>
|
||||
|
||||
<body id="Body-Container" class="body_container">
|
||||
|
||||
<section id="System-Nav-Menu">Site-Nav-Menu</section>
|
||||
|
||||
<div id="Site-Container">
|
||||
|
||||
<section id="Site-Header">Site-Header</section>
|
||||
|
||||
<nav id="Site-Nav-Menu">Site-Nav-Menu</nav>
|
||||
|
||||
<section id="Notifications">
|
||||
<section id="System-Notifications">System-Notifications (and Site-Notifications)</section><!-- and what would be Site-Notifications-->
|
||||
|
||||
</section>
|
||||
|
||||
<section id="Main-Body" class="main_template_content svelte_target event_launcher_main Side-Main-Nav-Menu">
|
||||
<section id="Main-Nav-Menu"></section>
|
||||
<main id="Main-Content"></main>
|
||||
</section>
|
||||
|
||||
<section id="Site-Footer">Site-Footer</section>
|
||||
|
||||
</div>
|
||||
|
||||
<section id="Site-Modals"></section>
|
||||
|
||||
<section id="System-Footer">Site-Footer</section>
|
||||
|
||||
<section id="System-Debug">System-Debug</section>
|
||||
|
||||
</body>
|
||||
<!-- JavaScript (JS) start -->
|
||||
<!-- <script>const app = require('./js/app_v3');</script> -->
|
||||
<!-- <script src="js/app_v3.js"></script> -->
|
||||
<script>
|
||||
/* ***** **** *** ** * ### * ** *** **** ***** */
|
||||
/* ***** **** *** ** * ### * ** *** **** ***** */
|
||||
</script>
|
||||
<!-- JavaScript (JS) end -->
|
||||
|
||||
|
||||
</html>
|
||||
69
dist/main/api_client.js
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.fetchFullConfig = fetchFullConfig;
|
||||
async function fetchFullConfig(seed) {
|
||||
const apiUrls = [
|
||||
seed.onsite_api_base_url,
|
||||
seed.primary_api_base_url,
|
||||
seed.backup_api_base_url
|
||||
].filter(url => url !== null && url !== undefined);
|
||||
let lastError = null;
|
||||
for (const baseUrl of apiUrls) {
|
||||
try {
|
||||
console.log(`Bootstrap: Attempting connection to ${baseUrl}...`);
|
||||
// --- STEP 1: Get Device Config ---
|
||||
const deviceUrl = `${baseUrl}/v3/crud/event_device/${seed.event_device_id}`;
|
||||
const deviceResponse = await fetch(deviceUrl, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'x-aether-api-key': seed.aether_api_key,
|
||||
'x-no-account-id': 'Nothing to See Here'
|
||||
},
|
||||
});
|
||||
if (!deviceResponse.ok) {
|
||||
throw new Error(`Device lookup failed (${deviceResponse.status})`);
|
||||
}
|
||||
const deviceResult = await deviceResponse.json();
|
||||
const deviceData = deviceResult.data || deviceResult;
|
||||
// Use 'app_base_url' as the FQDN for the site lookup
|
||||
const fqdn = deviceData.app_base_url || 'native-demo.oneskyit.com';
|
||||
console.log(`Bootstrap Step 1 Success: Device identified. FQDN to use: ${fqdn}`);
|
||||
// --- STEP 2: Get Site Context ---
|
||||
const searchUrl = `${baseUrl}/v3/crud/site_domain/search`;
|
||||
const siteResponse = await fetch(searchUrl, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'x-aether-api-key': seed.aether_api_key,
|
||||
'x-no-account-id': 'Nothing to See Here',
|
||||
'x-account-id': deviceData.account_id_random || deviceData.account_id || ''
|
||||
},
|
||||
body: JSON.stringify({
|
||||
search_query: {
|
||||
and: [{ field: 'fqdn', op: 'eq', value: fqdn }]
|
||||
},
|
||||
limit: 1
|
||||
})
|
||||
});
|
||||
if (!siteResponse.ok) {
|
||||
throw new Error(`Site context lookup failed (${siteResponse.status})`);
|
||||
}
|
||||
const siteResult = await siteResponse.json();
|
||||
const siteDomain = (siteResult.data && siteResult.data.length > 0) ? siteResult.data[0] : null;
|
||||
console.log(`Bootstrap Success using ${baseUrl}`);
|
||||
return {
|
||||
...siteDomain,
|
||||
native_device: deviceData
|
||||
};
|
||||
}
|
||||
catch (error) {
|
||||
console.warn(`Bootstrap failed for ${baseUrl}: `, error);
|
||||
lastError = error;
|
||||
continue; // Try next URL
|
||||
}
|
||||
}
|
||||
console.error('Bootstrap Critical Failure: All API endpoints exhausted.', lastError);
|
||||
return null;
|
||||
}
|
||||
//# sourceMappingURL=api_client.js.map
|
||||
1
dist/main/api_client.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"api_client.js","sourceRoot":"","sources":["../../src/main/api_client.ts"],"names":[],"mappings":";;AAEA,0CA4EC;AA5EM,KAAK,UAAU,eAAe,CAAC,IAAgB;IACpD,MAAM,OAAO,GAAG;QACd,IAAI,CAAC,mBAAmB;QACxB,IAAI,CAAC,oBAAoB;QACzB,IAAI,CAAC,mBAAmB;KACzB,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS,CAAa,CAAC;IAE/D,IAAI,SAAS,GAAQ,IAAI,CAAC;IAE1B,KAAK,MAAM,OAAO,IAAI,OAAO,EAAE,CAAC;QAC9B,IAAI,CAAC;YACH,OAAO,CAAC,GAAG,CAAC,uCAAuC,OAAO,KAAK,CAAC,CAAC;YAEjE,oCAAoC;YACpC,MAAM,SAAS,GAAG,GAAG,OAAO,yBAAyB,IAAI,CAAC,eAAe,EAAE,CAAC;YAC5E,MAAM,cAAc,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE;gBAC5C,MAAM,EAAE,KAAK;gBACb,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;oBAClC,kBAAkB,EAAE,IAAI,CAAC,cAAc;oBACvC,iBAAiB,EAAE,qBAAqB;iBACzC;aACF,CAAC,CAAC;YAEH,IAAI,CAAC,cAAc,CAAC,EAAE,EAAE,CAAC;gBACvB,MAAM,IAAI,KAAK,CAAC,yBAAyB,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC;YACrE,CAAC;YAED,MAAM,YAAY,GAAG,MAAM,cAAc,CAAC,IAAI,EAAE,CAAC;YACjD,MAAM,UAAU,GAAG,YAAY,CAAC,IAAI,IAAI,YAAY,CAAC;YAErD,qDAAqD;YACrD,MAAM,IAAI,GAAG,UAAU,CAAC,YAAY,IAAI,0BAA0B,CAAC;YACnE,OAAO,CAAC,GAAG,CAAC,6DAA6D,IAAI,EAAE,CAAC,CAAC;YAEjF,mCAAmC;YACnC,MAAM,SAAS,GAAG,GAAG,OAAO,6BAA6B,CAAC;YAC1D,MAAM,YAAY,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE;gBAC1C,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;oBAClC,kBAAkB,EAAE,IAAI,CAAC,cAAc;oBACvC,iBAAiB,EAAE,qBAAqB;oBACxC,cAAc,EAAE,UAAU,CAAC,iBAAiB,IAAI,UAAU,CAAC,UAAU,IAAI,EAAE;iBAC5E;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACnB,YAAY,EAAE;wBACZ,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;qBAChD;oBACD,KAAK,EAAE,CAAC;iBACT,CAAC;aACH,CAAC,CAAC;YAEH,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC;gBACrB,MAAM,IAAI,KAAK,CAAC,+BAA+B,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC;YACzE,CAAC;YAED,MAAM,UAAU,GAAG,MAAM,YAAY,CAAC,IAAI,EAAE,CAAC;YAC7C,MAAM,UAAU,GAAG,CAAC,UAAU,CAAC,IAAI,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAE/F,OAAO,CAAC,GAAG,CAAC,2BAA2B,OAAO,EAAE,CAAC,CAAC;YAElD,OAAO;gBACL,GAAG,UAAU;gBACb,aAAa,EAAE,UAAU;aAC1B,CAAC;QAEJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,wBAAwB,OAAO,IAAI,EAAE,KAAK,CAAC,CAAC;YACzD,SAAS,GAAG,KAAK,CAAC;YAClB,SAAS,CAAC,eAAe;QAC3B,CAAC;IACH,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,0DAA0D,EAAE,SAAS,CAAC,CAAC;IACrF,OAAO,IAAI,CAAC;AACd,CAAC"}
|
||||
62
dist/main/config_loader.js
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.loadSeedConfig = loadSeedConfig;
|
||||
const fs = __importStar(require("fs"));
|
||||
const path = __importStar(require("path"));
|
||||
const os = __importStar(require("os"));
|
||||
async function loadSeedConfig() {
|
||||
// For development, we look in the home directory
|
||||
const configPath = path.join(os.homedir(), 'seed.json');
|
||||
try {
|
||||
if (!fs.existsSync(configPath)) {
|
||||
console.log(`Seed config not found at: ${configPath}`);
|
||||
return null;
|
||||
}
|
||||
const data = fs.readFileSync(configPath, 'utf-8');
|
||||
const config = JSON.parse(data);
|
||||
// Basic validation
|
||||
if (!config.event_device_id) {
|
||||
console.error('Invalid seed config: missing event_device_id');
|
||||
return null;
|
||||
}
|
||||
return config;
|
||||
}
|
||||
catch (error) {
|
||||
console.error('Error loading seed config:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=config_loader.js.map
|
||||
1
dist/main/config_loader.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"config_loader.js","sourceRoot":"","sources":["../../src/main/config_loader.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,wCAwBC;AA7BD,uCAAyB;AACzB,2CAA6B;AAC7B,uCAAyB;AAGlB,KAAK,UAAU,cAAc;IAClC,iDAAiD;IACjD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAC;IAExD,IAAI,CAAC;QACH,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/B,OAAO,CAAC,GAAG,CAAC,6BAA6B,UAAU,EAAE,CAAC,CAAC;YACvD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAe,CAAC;QAE9C,mBAAmB;QACnB,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;YAC5B,OAAO,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;YAC9D,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAC;QACnD,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
||||
99
dist/main/index.js
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const electron_1 = require("electron");
|
||||
const path = __importStar(require("path"));
|
||||
const config_loader_1 = require("./config_loader");
|
||||
const api_client_1 = require("./api_client");
|
||||
let mainWindow = null;
|
||||
let cachedSeed = null;
|
||||
let cachedFullConfig = null;
|
||||
async function createWindow() {
|
||||
// 1. Initial Load of Configs
|
||||
cachedSeed = await (0, config_loader_1.loadSeedConfig)();
|
||||
if (cachedSeed) {
|
||||
cachedFullConfig = await (0, api_client_1.fetchFullConfig)(cachedSeed);
|
||||
}
|
||||
mainWindow = new electron_1.BrowserWindow({
|
||||
width: 1400,
|
||||
height: 900,
|
||||
title: 'OSIT Aether Launcher (Native)',
|
||||
webPreferences: {
|
||||
preload: path.join(__dirname, '../preload/index.js'),
|
||||
contextIsolation: true,
|
||||
nodeIntegration: false,
|
||||
},
|
||||
});
|
||||
// Prioritize demo.localhost for local development
|
||||
const devUrl = 'http://demo.localhost:5173';
|
||||
// Fallback URL if local is offline
|
||||
const fallbackUrl = 'https://dev-demo.oneskyit.com/';
|
||||
console.log(`Loading UI from: ${devUrl}`);
|
||||
mainWindow.loadURL(devUrl).catch(() => {
|
||||
console.warn(`Failed to load ${devUrl}. Falling back to ${fallbackUrl}`);
|
||||
mainWindow?.loadURL(fallbackUrl);
|
||||
});
|
||||
mainWindow.on('closed', () => {
|
||||
mainWindow = null;
|
||||
});
|
||||
}
|
||||
electron_1.app.on('ready', createWindow);
|
||||
electron_1.app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
electron_1.app.quit();
|
||||
}
|
||||
});
|
||||
electron_1.app.on('activate', () => {
|
||||
if (mainWindow === null) {
|
||||
createWindow();
|
||||
}
|
||||
});
|
||||
// IPC Handlers
|
||||
electron_1.ipcMain.handle('get-seed-config', async () => {
|
||||
return cachedSeed || await (0, config_loader_1.loadSeedConfig)();
|
||||
});
|
||||
electron_1.ipcMain.handle('get-device-config', async () => {
|
||||
if (cachedFullConfig)
|
||||
return cachedFullConfig;
|
||||
if (cachedSeed) {
|
||||
cachedFullConfig = await (0, api_client_1.fetchFullConfig)(cachedSeed);
|
||||
return cachedFullConfig;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
electron_1.ipcMain.handle('get-jwt', async () => {
|
||||
return null;
|
||||
});
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
dist/main/index.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/main/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAuD;AACvD,2CAA6B;AAC7B,mDAAiD;AACjD,6CAA+C;AAG/C,IAAI,UAAU,GAAyB,IAAI,CAAC;AAC5C,IAAI,UAAU,GAAsB,IAAI,CAAC;AACzC,IAAI,gBAAgB,GAAQ,IAAI,CAAC;AAEjC,KAAK,UAAU,YAAY;IACzB,6BAA6B;IAC7B,UAAU,GAAG,MAAM,IAAA,8BAAc,GAAE,CAAC;IACpC,IAAI,UAAU,EAAE,CAAC;QACf,gBAAgB,GAAG,MAAM,IAAA,4BAAe,EAAC,UAAU,CAAC,CAAC;IACvD,CAAC;IAED,UAAU,GAAG,IAAI,wBAAa,CAAC;QAC7B,KAAK,EAAE,IAAI;QACX,MAAM,EAAE,GAAG;QACX,KAAK,EAAE,+BAA+B;QACtC,cAAc,EAAE;YACd,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,qBAAqB,CAAC;YACpD,gBAAgB,EAAE,IAAI;YACtB,eAAe,EAAE,KAAK;SACvB;KACF,CAAC,CAAC;IAEH,kDAAkD;IAClD,MAAM,MAAM,GAAG,4BAA4B,CAAC;IAC5C,mCAAmC;IACnC,MAAM,WAAW,GAAG,gCAAgC,CAAC;IAErD,OAAO,CAAC,GAAG,CAAC,oBAAoB,MAAM,EAAE,CAAC,CAAC;IAE1C,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;QACpC,OAAO,CAAC,IAAI,CAAC,kBAAkB,MAAM,qBAAqB,WAAW,EAAE,CAAC,CAAC;QACzE,UAAU,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;QAC3B,UAAU,GAAG,IAAI,CAAC;IACpB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,cAAG,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;AAE9B,cAAG,CAAC,EAAE,CAAC,mBAAmB,EAAE,GAAG,EAAE;IAC/B,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,cAAG,CAAC,IAAI,EAAE,CAAC;IACb,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,cAAG,CAAC,EAAE,CAAC,UAAU,EAAE,GAAG,EAAE;IACtB,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;QACxB,YAAY,EAAE,CAAC;IACjB,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,eAAe;AACf,kBAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,KAAK,IAAI,EAAE;IAC3C,OAAO,UAAU,IAAI,MAAM,IAAA,8BAAc,GAAE,CAAC;AAC9C,CAAC,CAAC,CAAC;AAEH,kBAAO,CAAC,MAAM,CAAC,mBAAmB,EAAE,KAAK,IAAI,EAAE;IAC7C,IAAI,gBAAgB;QAAE,OAAO,gBAAgB,CAAC;IAC9C,IAAI,UAAU,EAAE,CAAC;QACf,gBAAgB,GAAG,MAAM,IAAA,4BAAe,EAAC,UAAU,CAAC,CAAC;QACrD,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC,CAAC;AAEH,kBAAO,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;IACnC,OAAO,IAAI,CAAC;AACd,CAAC,CAAC,CAAC"}
|
||||
10
dist/preload/index.js
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const electron_1 = require("electron");
|
||||
electron_1.contextBridge.exposeInMainWorld('aetherNative', {
|
||||
getSeedConfig: () => electron_1.ipcRenderer.invoke('get-seed-config'),
|
||||
getDeviceConfig: () => electron_1.ipcRenderer.invoke('get-device-config'),
|
||||
getJWT: () => electron_1.ipcRenderer.invoke('get-jwt'),
|
||||
log: (message) => console.log('[Native Log]', message),
|
||||
});
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
dist/preload/index.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/preload/index.ts"],"names":[],"mappings":";;AAAA,uCAAsD;AAEtD,wBAAa,CAAC,iBAAiB,CAAC,cAAc,EAAE;IAC9C,aAAa,EAAE,GAAG,EAAE,CAAC,sBAAW,CAAC,MAAM,CAAC,iBAAiB,CAAC;IAC1D,eAAe,EAAE,GAAG,EAAE,CAAC,sBAAW,CAAC,MAAM,CAAC,mBAAmB,CAAC;IAC9D,MAAM,EAAE,GAAG,EAAE,CAAC,sBAAW,CAAC,MAAM,CAAC,SAAS,CAAC;IAC3C,GAAG,EAAE,CAAC,OAAe,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,OAAO,CAAC;CAC/D,CAAC,CAAC"}
|
||||
3
dist/shared/types.js
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
//# sourceMappingURL=types.js.map
|
||||
1
dist/shared/types.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/shared/types.ts"],"names":[],"mappings":""}
|
||||
586
index.js
@@ -1,586 +0,0 @@
|
||||
const { app, BrowserWindow, ipcMain, shell, systemPreferences } = require('electron');
|
||||
|
||||
|
||||
const axios = require('axios');
|
||||
const crypto = require('crypto');
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
const path = require('path');
|
||||
const process = require('process');
|
||||
const { strict } = require('assert');
|
||||
|
||||
//const http = require('http');
|
||||
//const request = require('request');
|
||||
//const url = require('url');
|
||||
// const usb = require('usb') // Compiled with an old version of Node.js
|
||||
|
||||
console.log(`OS: ${os.type()} ${process.getSystemVersion()}`);
|
||||
// console.log(process.getSystemVersion());
|
||||
|
||||
let home_directory = require('os').homedir();
|
||||
console.log('Home: '+home_directory);
|
||||
|
||||
let tmp_directory = require('os').tmpdir();
|
||||
console.log('Temporary: '+tmp_directory);
|
||||
|
||||
// Set the config path for macOS or Linux
|
||||
let config_directory = 'OSIT/native_app';
|
||||
let config_filename = 'ae_native_app_sk_config.json';
|
||||
let config_path = '';
|
||||
|
||||
let local_file_cache_path = null;
|
||||
let host_file_temp_path = null;
|
||||
|
||||
let endpoints_in_progress = [];
|
||||
|
||||
/* Look for and load a JSON formatted config file. */
|
||||
if (os.platform == 'darwin') {
|
||||
let config_path_default = path.join(home_directory, config_directory, config_filename);
|
||||
let config_path_macos = path.join(home_directory, 'Library/Application Support/OSIT', config_filename);
|
||||
// let config_path_opt2 = path.join(home_directory, 'OSIT', config_filename);
|
||||
|
||||
if (fs.existsSync(config_path_default)) {
|
||||
console.log('Default config file path exists: '+config_path_default);
|
||||
config_path = config_path_default;
|
||||
} else if (fs.existsSync(config_path_macos)) {
|
||||
console.log('macOS config file path exists: '+config_path_macos);
|
||||
config_path = config_path_macos;
|
||||
} else {
|
||||
console.log(`No config file found: ${config_path_default} or ${config_path_macos}`);
|
||||
config_path = '';
|
||||
// fs.mkdirSync(config_file_directory_path, true);
|
||||
// console.log('Config directory path created: '+config_file_directory_path);
|
||||
}
|
||||
|
||||
console.log(`Using config found on macOS: ${config_path}`);
|
||||
} else if (os.platform == 'linux') {
|
||||
let config_path_default = path.join(home_directory, config_directory, config_filename);
|
||||
let config_path_linux_os = path.join(home_directory, '.config/OSIT', config_filename);
|
||||
let config_path_temp = path.join(home_directory, 'tmp/OSIT', config_filename);
|
||||
|
||||
if (fs.existsSync(config_path_default)) {
|
||||
console.log('Default config file path exists: '+config_path_default);
|
||||
config_path = config_path_default;
|
||||
} else if (fs.existsSync(config_path_linux_os)) {
|
||||
console.log('Linux config file path exists: '+config_path_linux_os);
|
||||
config_path = config_path_linux_os;
|
||||
} else if (fs.existsSync(config_path_temp)) {
|
||||
console.log('Temp config file path exists: '+config_path_temp);
|
||||
config_path = config_path_temp;
|
||||
} else {
|
||||
console.log(`No config file found: ${config_path_default} or ${config_path_linux_os} or ${config_path_temp}`);
|
||||
config_path = '';
|
||||
}
|
||||
|
||||
console.log(`Using config found on Linux: ${config_path}`);
|
||||
}
|
||||
|
||||
let config = JSON.parse(fs.readFileSync(config_path));
|
||||
console.log('Config file read.', config);
|
||||
/*
|
||||
Minimal configuration contains:
|
||||
* conf_file_check_path = '~/OSIT/sync/admin_share/internal/ae_osit_app.default.conf'
|
||||
* conf_file_check_path_backup = 'ae_osit_app.conf'
|
||||
|
||||
* api_pref_use = 'local' or 'remote' or 'backup'
|
||||
* api_base_url_local = https://local-api.oneskyit.com
|
||||
* api_base_url_remote = https://api.oneskyit.com
|
||||
* api_base_url_backup = https://bak-api.oneskyit.com
|
||||
|
||||
* app_pref_use = 'local' or 'remote' or 'backup'
|
||||
* app_base_url_local = https://local-demo.oneskyit.com
|
||||
* app_base_url_remote = https://demo.oneskyit.com
|
||||
* app_base_url_backup = https://bak-demo.oneskyit.com
|
||||
|
||||
* device_id = 'abcd1234'
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
Ask for permissions from macOS to use the microphone, screen, camera. The OS may delay actually asking for permission until the permission is actually attempted to be used. It may be worth doing a test attempt early on if access has not already been granted. -STI 2023-06-03
|
||||
*/
|
||||
if (os.type == 'Darwin') {
|
||||
if (systemPreferences.getMediaAccessStatus('microphone') != 'granted') {
|
||||
systemPreferences.askForMediaAccess('microphone');
|
||||
} else {
|
||||
console.log('Microphone access:', systemPreferences.getMediaAccessStatus('microphone'));
|
||||
}
|
||||
|
||||
if (systemPreferences.getMediaAccessStatus('screen') != 'granted') {
|
||||
systemPreferences.askForMediaAccess('screen');
|
||||
} else {
|
||||
console.log('Screen access:', systemPreferences.getMediaAccessStatus('screen'));
|
||||
}
|
||||
|
||||
if (systemPreferences.getMediaAccessStatus('camera') != 'granted') {
|
||||
systemPreferences.askForMediaAccess('camera');
|
||||
} else {
|
||||
console.log('Camera access:', systemPreferences.getMediaAccessStatus('camera'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
async function get_url_cfg() {
|
||||
let base_url = `${config.api_protocol}://${config.api_server}:${config.api_port}/${config.api_path}`;
|
||||
|
||||
let axios_api = axios.create({
|
||||
baseURL: base_url,
|
||||
timeout: 60000, // in milliseconds; 60000 = 60 seconds
|
||||
/* other custom settings */
|
||||
});
|
||||
// axios_api.defaults.headers = config['headers'];
|
||||
|
||||
// axios.defaults.baseURL = `${config.api_protocol}://${config.api_server}:${config.api_port}/${config.api_path}`;
|
||||
axios_api.defaults.headers.common['Access-Control-Allow-Origin'] = config.access_control_allow_origin; // '*'; // app_config.access_control_allow_origin;
|
||||
axios_api.defaults.headers.common['content-type'] = 'application/json';
|
||||
axios_api.defaults.headers.common['x-aether-api-key'] = config.api_secret_key;
|
||||
// axios_api.defaults.headers.common['x-account-id'] = config.account_id ?? 'xFP7AhU8Zlc';
|
||||
axios_api.defaults.headers.common['x-no-account-id'] = 'nothing to see here';
|
||||
|
||||
let event_device_id = config.event_device_id ?? 'dbgMWS3KEHE';
|
||||
// let endpoint = `/event/device/${event_device_id}`;
|
||||
let endpoint = `/v2/crud/event/device/${event_device_id}`;
|
||||
|
||||
let params = {
|
||||
inc_event_cfg: false,
|
||||
inc_event_location: false,
|
||||
enabled: 'enabled',
|
||||
};
|
||||
|
||||
let response_data_promise = await axios_api.get(
|
||||
endpoint,
|
||||
{
|
||||
params: params,
|
||||
onDownloadProgress: (progressEvent) => {
|
||||
let percent_completed = Math.round(
|
||||
(progressEvent.loaded * 100) / progressEvent.total
|
||||
);
|
||||
console.log('GET Data Timestamp:', progressEvent.timeStamp, 'Total:', progressEvent.total, 'Loaded:', progressEvent.loaded, 'Percent Completed', percent_completed);
|
||||
|
||||
// temp_get_object_percent_completed = percent_completed;
|
||||
}
|
||||
}
|
||||
)
|
||||
.then(function (response) {
|
||||
console.log(`Response: ${response}`);
|
||||
|
||||
let return_data = response.data['data'];
|
||||
if (Array.isArray(return_data)) {
|
||||
console.log(`Data result is an array/list. Array length: ${return_data.length}`);
|
||||
} else {
|
||||
console.log(`Data result is a dictionary/object, not an array/list.`);
|
||||
}
|
||||
return return_data;
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.log(`Base URL: ${base_url} | Endpoint: ${endpoint}`);
|
||||
|
||||
console.log('Error Message:', error.message); // Is this needed here or below in the in the else portion???
|
||||
if (error.response) {
|
||||
console.log(`Response Status: ${error.response.status}; Status Text: ${error.response.statusText}`);
|
||||
} else {
|
||||
console.log('Error:', error);
|
||||
}
|
||||
|
||||
console.log('Full Error:', error);
|
||||
|
||||
if (error.response && error.response.status === 404) {
|
||||
return null; // Returning null since there were no results
|
||||
}
|
||||
return false; // Returning false since something may have gone wrong. Also more in line with what the API returns.
|
||||
});
|
||||
|
||||
return response_data_promise;
|
||||
}
|
||||
|
||||
let new_config = get_url_cfg();
|
||||
console.log(new_config);
|
||||
|
||||
|
||||
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
win = new BrowserWindow({
|
||||
height: config.height ?? 720,
|
||||
width: config.width ?? 1280,
|
||||
backgroundColor: '#aaa',
|
||||
icon: './app/img/favicon.ico',
|
||||
webPreferences: {
|
||||
contextIsolation: false,
|
||||
nodeIntegration: true,
|
||||
nodeIntegrationInWorker: true,
|
||||
enableRemoteModule: true
|
||||
}
|
||||
})
|
||||
|
||||
// win.setMinimumSize(1024, 768);
|
||||
// win.setMinimumSize(1280, 768);
|
||||
win.setMinimumSize(1400, 768);
|
||||
|
||||
//win.setFullScreenable(false)
|
||||
win.FullScreenable = false;
|
||||
|
||||
// win.webContents.session.clearStorageData(['filesystem']); // Does this do anything???
|
||||
|
||||
// native_app_which_html = 'default', 'path', 'url'
|
||||
// 'default' (url) is within the bundled native app
|
||||
// 'path' (external to app) is a file path on the host, probably under the home directory
|
||||
// 'url' is over HTTPS, maybe onsite or offsite
|
||||
// unknown points to an index.html file in the app directory
|
||||
|
||||
// Load the index.html of the app
|
||||
if (config.native_app_which_html == '' || config.native_app_which_html == 'default') {
|
||||
// win.loadFile('app/index.html');
|
||||
let index_url = config.native_app_index_url ?? 'https://oneskyit.com/';
|
||||
win.loadURL(index_url);
|
||||
} else if (config.native_app_which_html == 'path') {
|
||||
let index_path = '';
|
||||
|
||||
if (config.native_app_index_path) {
|
||||
index_path = config.native_app_index_path.replace('[home]', home_directory);
|
||||
} else {
|
||||
index_path = path.join(home_directory, 'OSIT/native_app/app/index.html');
|
||||
}
|
||||
win.loadFile(index_path);
|
||||
} else if (config.native_app_which_html == 'url') {
|
||||
let index_url = config.native_app_index_url ?? 'https://oneskyit.com/';
|
||||
win.loadURL(index_url);
|
||||
} else {
|
||||
win.loadFile('app/index.html');
|
||||
}
|
||||
|
||||
// Open the DevTools.
|
||||
if (config.developer_tools) {
|
||||
win.webContents.openDevTools(); // Comment out for production
|
||||
}
|
||||
|
||||
// Emitted when the window is closed.
|
||||
win.on('closed', () => {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
win = null;
|
||||
})
|
||||
|
||||
win.on('minimize', () => {
|
||||
//win.restore();
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.on('ready', createWindow);
|
||||
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', () => {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
if (win) {
|
||||
win.close();
|
||||
}
|
||||
app.quit();
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
app.on('activate', () => {
|
||||
// On macOS it's common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.location_files
|
||||
if (win === null) {
|
||||
createWindow();
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
// Import config data
|
||||
// Updated 2022-04-16
|
||||
ipcMain.handle('import_config', async (event, config_data) => {
|
||||
console.log('*** Electron IPC Main: import_config() ***');
|
||||
// console.log('ipcMain on download_file: api_base_url='+api_base_url+' | api_temporary_token='+api_temporary_token);
|
||||
console.log('ipcMain on import_config:');
|
||||
console.log(config_data);
|
||||
|
||||
config = config_data;
|
||||
|
||||
local_file_cache_path = config.local_file_cache_path;
|
||||
host_file_temp_path = config.host_file_temp_path;
|
||||
|
||||
if (fs.existsSync(local_file_cache_path)) {
|
||||
console.log('Host file cache path exists: '+local_file_cache_path);
|
||||
} else {
|
||||
fs.mkdirSync(local_file_cache_path, true);
|
||||
console.log('Host file cache path created: '+local_file_cache_path);
|
||||
}
|
||||
|
||||
if (fs.existsSync(host_file_temp_path)) {
|
||||
console.log('Host file temp path exists: '+host_file_temp_path);
|
||||
} else {
|
||||
fs.mkdirSync(host_file_temp_path, true);
|
||||
console.log('Host file temp path created: '+host_file_temp_path);
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
|
||||
// Download file to path
|
||||
// full_save_path should be the full path that includes the filename
|
||||
// Updated 2023-05-14
|
||||
ipcMain.handle('download_file', async (event, api_base_url, api_endpoint, full_save_path, hash=null, verify_hash=false, overwrite_existing=false, offset_minutes=3) => {
|
||||
console.log('*** Electron IPC Main: download_file() ***');
|
||||
// console.log('ipcMain on download_file: api_base_url='+api_base_url+' | api_temporary_token='+api_temporary_token);
|
||||
// console.log('ipcMain on download_file: api_base_url='+api_base_url);
|
||||
console.log(`ipcMain download and save file: HTTP ${api_endpoint} -> FILE ${full_save_path}`);
|
||||
if (!api_base_url) {
|
||||
console.log('API Base URL is required. Returning false');
|
||||
return false;
|
||||
}
|
||||
|
||||
axios.defaults.baseURL = api_base_url;
|
||||
axios.defaults.headers.common['Access-Control-Allow-Origin'] = config.access_control_allow_origin; // '*'; // app_config.access_control_allow_origin;
|
||||
axios.defaults.headers.common['content-type'] = 'application/json';
|
||||
axios.defaults.headers.common['x-aether-api-key'] = config.api_secret_key;
|
||||
axios.defaults.headers.common['x-account-id'] = config.account_id;
|
||||
|
||||
const url = api_endpoint;
|
||||
|
||||
const tmp_full_save_path = full_save_path+'.tmp';
|
||||
|
||||
if (fs.existsSync(tmp_full_save_path)) {
|
||||
console.log(`A temp download file was found! ${tmp_full_save_path}`);
|
||||
|
||||
let stats = null;
|
||||
try {
|
||||
stats = fs.statSync(tmp_full_save_path);
|
||||
|
||||
// console.log(`File Accessed Last: ${stats.atime}`); // File data last changed (actual contents)
|
||||
console.log(`File Data Last Modified: ${stats.mtime}`); // File data last changed (actual contents)
|
||||
console.log(`File Metadata Last Modified: ${stats.ctime}`); // File metadata last changed (filename, permissions, etc)
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
let current_datetime = new Date();
|
||||
// In minutes. After 5ish minutes of no changes to the file content seems reasonable? Tested with 3 minutes for multiple meetings and no noticable problem.
|
||||
let offset_datetime = new Date(current_datetime.getTime() - offset_minutes*60000);
|
||||
|
||||
// console.log(`Times: ${current_datetime} ${offset_datetime} | File ${stats.mtime}`);
|
||||
if (stats.mtime < offset_datetime) {
|
||||
console.log(`Marking as expired temp file based on modified datetime. Expire after: ${offset_minutes} minutes`);
|
||||
overwrite_existing = true;
|
||||
} else {
|
||||
console.log(`Temp download file has not expired yet. Expire after: ${offset_minutes} minutes`);
|
||||
// return false;
|
||||
return 'tmp';
|
||||
}
|
||||
}
|
||||
if (fs.existsSync(full_save_path)) {
|
||||
console.log(`A cached file was found! ${full_save_path}`);
|
||||
if (verify_hash) {
|
||||
const file_buffer = fs.readFileSync(full_save_path);
|
||||
const file_hash_sha256 = crypto.createHash('sha256');
|
||||
file_hash_sha256.update(file_buffer);
|
||||
|
||||
const file_hash_sha256_check = file_hash_sha256.digest('hex');
|
||||
if (file_hash_sha256_check == hash) {
|
||||
// console.log('File hash match', file_hash_sha256_check);
|
||||
} else {
|
||||
console.log('File hash does not match', file_hash_sha256_check);
|
||||
if (overwrite_existing) {
|
||||
console.log('Going to overwrite the existing file because the hash does not match.');
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// return false;
|
||||
}
|
||||
|
||||
console.log('Endpoints in Progress:', endpoints_in_progress);
|
||||
if (endpoints_in_progress.includes(api_endpoint)) {
|
||||
console.log(`Endpoint already being downloaded: ${api_endpoint}`);
|
||||
// return false;
|
||||
return 'in_progress';
|
||||
}
|
||||
// console.log(`Done with checks. Time to download! Endpoint: ${api_endpoint}`);
|
||||
endpoints_in_progress.push(api_endpoint);
|
||||
|
||||
let download_result = await axios({
|
||||
method: 'get',
|
||||
url: url,
|
||||
responseType: 'stream' /* responseType must be stream */
|
||||
}).then(function (response) {
|
||||
console.log(`Creating write stream for downloading endpoint: ${api_endpoint}`);
|
||||
const writer = fs.createWriteStream(tmp_full_save_path);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
response.data.pipe(writer);
|
||||
let error = null;
|
||||
writer.on('error', err => {
|
||||
console.log('Writer error!');
|
||||
error = err;
|
||||
console.log(error);
|
||||
writer.close();
|
||||
reject(err);
|
||||
});
|
||||
writer.on('close', () => {
|
||||
|
||||
if (!error) {
|
||||
// console.log(`Download complete! Writer closed.`);
|
||||
resolve(true);
|
||||
} else {
|
||||
console.log('Writer closed unexpectedly!', error);
|
||||
}
|
||||
//no need to call the reject here, as it will have been called in the
|
||||
//'error' stream;
|
||||
});
|
||||
});
|
||||
})
|
||||
.then(function (response) {
|
||||
console.log(`Download complete. Temporary file moved/renamed: ${full_save_path}`);
|
||||
fs.renameSync(tmp_full_save_path, full_save_path);
|
||||
|
||||
for( let i = 0; i < endpoints_in_progress.length; i++){
|
||||
if ( endpoints_in_progress[i] === api_endpoint) {
|
||||
endpoints_in_progress.splice(i, 1);
|
||||
// NOTE: Decrement the index variable so it does not skip the next item in the array.
|
||||
i--;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.log(`Error downloading! Endpoint: ${api_endpoint}`);
|
||||
|
||||
for( let i = 0; i < endpoints_in_progress.length; i++){
|
||||
if ( endpoints_in_progress[i] === api_endpoint) {
|
||||
endpoints_in_progress.splice(i, 1);
|
||||
// NOTE: Decrement the index variable so it does not skip the next item in the array.
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
if (error.response) {
|
||||
console.log(`Response Status: ${error.response.status}; Status Text: ${error.response.statusText}`);
|
||||
} else {
|
||||
console.log('Error:', error);
|
||||
}
|
||||
|
||||
if (error.response && error.response.status === 404) {
|
||||
return null; // Returning null since there were no results
|
||||
}
|
||||
return false; // Returning false since something may have gone wrong. Also more in line with what the API returns.
|
||||
});
|
||||
// console.log(`Done with download function! Endpoint: ${api_endpoint}`);
|
||||
|
||||
return download_result;
|
||||
});
|
||||
|
||||
|
||||
ipcMain.handle('open_hash_file_to_temp', async (event, local_file_cache_path, hash, host_file_temp_path, filename, verify_hash=true) => {
|
||||
console.log('*** Electron IPC Main: open_hash_file_to_temp() ***');
|
||||
console.log('ipcMain on open_hash_file_to_temp');
|
||||
console.log(`ipcMain open hash file from temp directory: ${local_file_cache_path} -> ${host_file_temp_path}/${filename}`);
|
||||
|
||||
// NOTE: This may be needed later? Uncomment if paths are relative to working directory.
|
||||
// let cache_file_path = path.join(process.cwd(), local_file_cache_path);
|
||||
let cache_file_path = local_file_cache_path;
|
||||
console.log(cache_file_path);
|
||||
|
||||
let hash_filename = hash+'.file';
|
||||
let full_cache_file_path = path.join(cache_file_path, hash_filename);
|
||||
console.log(full_cache_file_path);
|
||||
|
||||
// NOTE: This may be needed later? Uncomment if paths are relative to working directory.
|
||||
// open_temp_file_path = path.join(process.cwd(), host_file_temp_path, filename); // 'temp/'
|
||||
open_temp_file_path = path.join(host_file_temp_path, filename); // 'temp/'
|
||||
console.log(open_temp_file_path);
|
||||
|
||||
if (fs.existsSync(open_temp_file_path)) {
|
||||
console.log('A file with the same name already exists in the local temp directory: '+open_temp_file_path);
|
||||
// NOTE: Should the file be checked to see if it has changed from the hashed cache version???
|
||||
// NOTE: What if they made changes to the file locally in temp? The changed file would be used since a new copy is not being made.
|
||||
// NOTE: It might make sense for this to be a configurable option depending on the group. Some do not allow changes. This helps enforce that.
|
||||
}
|
||||
|
||||
if (fs.existsSync(full_cache_file_path)) {
|
||||
// console.log(`Hashed file exists in cache: ${full_cache_file_path}`);
|
||||
console.log(`Copying file to temp: ${open_temp_file_path}`);
|
||||
try {
|
||||
fs.copyFileSync(full_cache_file_path, open_temp_file_path);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (verify_hash) {
|
||||
const file_buffer = fs.readFileSync(full_cache_file_path);
|
||||
const file_hash_sha256 = crypto.createHash('sha256');
|
||||
file_hash_sha256.update(file_buffer);
|
||||
|
||||
const file_hash_sha256_check = file_hash_sha256.digest('hex');
|
||||
if (file_hash_sha256_check == hash) {
|
||||
// console.log('File hash match', file_hash_sha256_check);
|
||||
} else {
|
||||
console.log('File hash does not match', file_hash_sha256_check);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// console.log('Creating file link: '+open_temp_file_path);
|
||||
// fs.linkSync(full_cache_file_path, open_temp_file_path);
|
||||
} else {
|
||||
console.log(`Hashed file not found in cache: ${full_cache_file_path}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
await shell.openPath(open_temp_file_path);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
console.log('End: Electron IPC Main: open_hash_file_to_temp()');
|
||||
return true;
|
||||
});
|
||||
|
||||
|
||||
ipcMain.handle('open_local_file', async (event, local_file_path, filename, use_cwd=true) => {
|
||||
console.log('*** Electron IPC Main: open_local_file() ***');
|
||||
console.log('ipcMain on open_local_file');
|
||||
console.log(`ipcMain open local file from directory: ${local_file_path}/${filename}`);
|
||||
|
||||
let full_local_file_path = null;
|
||||
|
||||
if (use_cwd) {
|
||||
full_local_file_path = path.join(process.cwd(), local_file_path, filename);
|
||||
console.log(full_local_file_path);
|
||||
} else {
|
||||
full_local_file_path = path.join(local_file_path, filename);
|
||||
console.log(full_local_file_path);
|
||||
}
|
||||
|
||||
if (fs.existsSync(full_local_file_path)) {
|
||||
console.log(`Local file exists: ${full_local_file_path}`);
|
||||
} else {
|
||||
console.log(`Local file not found: ${full_local_file_path}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
await shell.openPath(full_local_file_path);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
console.log('End: Electron IPC Main: open_local_file()');
|
||||
return true;
|
||||
});
|
||||
2354
package-lock.json
generated
25
package.json
@@ -1,25 +0,0 @@
|
||||
{
|
||||
"name": "aether_app_native",
|
||||
"productName": "Aether App: Native",
|
||||
"version": "2024.8.14.1",
|
||||
"description": "One Sky IT's Native Aether App",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "electron .",
|
||||
"start_nogpu": "electron . --disable-gpu",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "Scott Idem",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"axios": "^1.1.2",
|
||||
"child_process": "^1.0.2",
|
||||
"fs": "^0.0.1-security",
|
||||
"os": "^0.1.2",
|
||||
"path": "^0.12.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"electron": "^31.0.0",
|
||||
"electron-packager": "^17.1.2"
|
||||
}
|
||||
}
|
||||
79
src/main/api_client.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import { SeedConfig } from '../shared/types';
|
||||
|
||||
export async function fetchFullConfig(seed: SeedConfig): Promise<any> {
|
||||
const apiUrls = [
|
||||
seed.onsite_api_base_url,
|
||||
seed.primary_api_base_url,
|
||||
seed.backup_api_base_url
|
||||
].filter(url => url !== null && url !== undefined) as string[];
|
||||
|
||||
let lastError: any = null;
|
||||
|
||||
for (const baseUrl of apiUrls) {
|
||||
try {
|
||||
console.log(`Bootstrap: Attempting connection to ${baseUrl}...`);
|
||||
|
||||
// --- STEP 1: Get Device Config ---
|
||||
const deviceUrl = `${baseUrl}/v3/crud/event_device/${seed.event_device_id}`;
|
||||
const deviceResponse = await fetch(deviceUrl, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'x-aether-api-key': seed.aether_api_key,
|
||||
'x-no-account-id': 'Nothing to See Here'
|
||||
},
|
||||
});
|
||||
|
||||
if (!deviceResponse.ok) {
|
||||
throw new Error(`Device lookup failed (${deviceResponse.status})`);
|
||||
}
|
||||
|
||||
const deviceResult = await deviceResponse.json();
|
||||
const deviceData = deviceResult.data || deviceResult;
|
||||
|
||||
// Use 'app_base_url' as the FQDN for the site lookup
|
||||
const fqdn = deviceData.app_base_url || 'native-demo.oneskyit.com';
|
||||
console.log(`Bootstrap Step 1 Success: Device identified. FQDN to use: ${fqdn}`);
|
||||
|
||||
// --- STEP 2: Get Site Context ---
|
||||
const searchUrl = `${baseUrl}/v3/crud/site_domain/search`;
|
||||
const siteResponse = await fetch(searchUrl, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'x-aether-api-key': seed.aether_api_key,
|
||||
'x-no-account-id': 'Nothing to See Here',
|
||||
'x-account-id': deviceData.account_id_random || deviceData.account_id || ''
|
||||
},
|
||||
body: JSON.stringify({
|
||||
search_query: {
|
||||
and: [{ field: 'fqdn', op: 'eq', value: fqdn }]
|
||||
},
|
||||
limit: 1
|
||||
})
|
||||
});
|
||||
|
||||
if (!siteResponse.ok) {
|
||||
throw new Error(`Site context lookup failed (${siteResponse.status})`);
|
||||
}
|
||||
|
||||
const siteResult = await siteResponse.json();
|
||||
const siteDomain = (siteResult.data && siteResult.data.length > 0) ? siteResult.data[0] : null;
|
||||
|
||||
console.log(`Bootstrap Success using ${baseUrl}`);
|
||||
|
||||
return {
|
||||
...siteDomain,
|
||||
native_device: deviceData
|
||||
};
|
||||
|
||||
} catch (error) {
|
||||
console.warn(`Bootstrap failed for ${baseUrl}: `, error);
|
||||
lastError = error;
|
||||
continue; // Try next URL
|
||||
}
|
||||
}
|
||||
|
||||
console.error('Bootstrap Critical Failure: All API endpoints exhausted.', lastError);
|
||||
return null;
|
||||
}
|
||||
30
src/main/config_loader.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as os from 'os';
|
||||
import { SeedConfig } from '../shared/types';
|
||||
|
||||
export async function loadSeedConfig(): Promise<SeedConfig | null> {
|
||||
// For development, we look in the home directory
|
||||
const configPath = path.join(os.homedir(), 'seed.json');
|
||||
|
||||
try {
|
||||
if (!fs.existsSync(configPath)) {
|
||||
console.log(`Seed config not found at: ${configPath}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
const data = fs.readFileSync(configPath, 'utf-8');
|
||||
const config = JSON.parse(data) as SeedConfig;
|
||||
|
||||
// Basic validation
|
||||
if (!config.event_device_id) {
|
||||
console.error('Invalid seed config: missing event_device_id');
|
||||
return null;
|
||||
}
|
||||
|
||||
return config;
|
||||
} catch (error) {
|
||||
console.error('Error loading seed config:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
76
src/main/index.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import { app, BrowserWindow, ipcMain } from 'electron';
|
||||
import * as path from 'path';
|
||||
import { loadSeedConfig } from './config_loader';
|
||||
import { fetchFullConfig } from './api_client';
|
||||
import { SeedConfig } from '../shared/types';
|
||||
|
||||
let mainWindow: BrowserWindow | null = null;
|
||||
let cachedSeed: SeedConfig | null = null;
|
||||
let cachedFullConfig: any = null;
|
||||
|
||||
async function createWindow() {
|
||||
// 1. Initial Load of Configs
|
||||
cachedSeed = await loadSeedConfig();
|
||||
if (cachedSeed) {
|
||||
cachedFullConfig = await fetchFullConfig(cachedSeed);
|
||||
}
|
||||
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 1400,
|
||||
height: 900,
|
||||
title: 'OSIT Aether Launcher (Native)',
|
||||
webPreferences: {
|
||||
preload: path.join(__dirname, '../preload/index.js'),
|
||||
contextIsolation: true,
|
||||
nodeIntegration: false,
|
||||
},
|
||||
});
|
||||
|
||||
// Prioritize demo.localhost for local development
|
||||
const devUrl = 'http://demo.localhost:5173';
|
||||
// Fallback URL if local is offline
|
||||
const fallbackUrl = 'https://dev-demo.oneskyit.com/';
|
||||
|
||||
console.log(`Loading UI from: ${devUrl}`);
|
||||
|
||||
mainWindow.loadURL(devUrl).catch(() => {
|
||||
console.warn(`Failed to load ${devUrl}. Falling back to ${fallbackUrl}`);
|
||||
mainWindow?.loadURL(fallbackUrl);
|
||||
});
|
||||
|
||||
mainWindow.on('closed', () => {
|
||||
mainWindow = null;
|
||||
});
|
||||
}
|
||||
|
||||
app.on('ready', createWindow);
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit();
|
||||
}
|
||||
});
|
||||
|
||||
app.on('activate', () => {
|
||||
if (mainWindow === null) {
|
||||
createWindow();
|
||||
}
|
||||
});
|
||||
|
||||
// IPC Handlers
|
||||
ipcMain.handle('get-seed-config', async () => {
|
||||
return cachedSeed || await loadSeedConfig();
|
||||
});
|
||||
|
||||
ipcMain.handle('get-device-config', async () => {
|
||||
if (cachedFullConfig) return cachedFullConfig;
|
||||
if (cachedSeed) {
|
||||
cachedFullConfig = await fetchFullConfig(cachedSeed);
|
||||
return cachedFullConfig;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
ipcMain.handle('get-jwt', async () => {
|
||||
return null;
|
||||
});
|
||||
8
src/preload/index.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { contextBridge, ipcRenderer } from 'electron';
|
||||
|
||||
contextBridge.exposeInMainWorld('aetherNative', {
|
||||
getSeedConfig: () => ipcRenderer.invoke('get-seed-config'),
|
||||
getDeviceConfig: () => ipcRenderer.invoke('get-device-config'),
|
||||
getJWT: () => ipcRenderer.invoke('get-jwt'),
|
||||
log: (message: string) => console.log('[Native Log]', message),
|
||||
});
|
||||
20
src/shared/types.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
export interface SeedConfig {
|
||||
event_device_id: string;
|
||||
primary_api_base_url: string;
|
||||
backup_api_base_url: string | null;
|
||||
onsite_api_base_url: string | null;
|
||||
aether_api_key: string;
|
||||
}
|
||||
|
||||
export interface AetherNativeBridge {
|
||||
getSeedConfig: () => Promise<SeedConfig | null>;
|
||||
getDeviceConfig: () => Promise<any>;
|
||||
getJWT: () => Promise<string | null>;
|
||||
log: (message: string) => void;
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
aetherNative: AetherNativeBridge;
|
||||
}
|
||||
}
|
||||
55
tests/test_device_lookup.py
Normal file
@@ -0,0 +1,55 @@
|
||||
import requests
|
||||
import json
|
||||
|
||||
def test_device_lookup():
|
||||
device_id = 'dbgMWS3KEHE'
|
||||
api_key = 'INSdG85ANwsEIru3nUttMw'
|
||||
base_url = 'https://dev-api.oneskyit.com'
|
||||
endpoint = f'{base_url}/v3/crud/event_device/{device_id}'
|
||||
|
||||
headers = {
|
||||
'x-aether-api-key': api_key,
|
||||
'x-no-account-id': 'Nothing to See Here',
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
|
||||
params = {
|
||||
'view': 'enriched'
|
||||
}
|
||||
|
||||
print(f'Testing lookup for device: {device_id}')
|
||||
print(f'Endpoint: {endpoint}')
|
||||
|
||||
try:
|
||||
response = requests.get(endpoint, headers=headers, params=params)
|
||||
print(f'Status Code: {response.status_code}')
|
||||
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
device_data = data.get('data', {})
|
||||
|
||||
print('Returned Fields (Key Values):')
|
||||
important_fields = [
|
||||
'account_id_random',
|
||||
'app_base_url',
|
||||
'code',
|
||||
'name',
|
||||
'event_id_random',
|
||||
'event_location_id_random',
|
||||
'local_file_cache_path',
|
||||
'host_file_temp_path',
|
||||
'recording_path',
|
||||
'cfg_json'
|
||||
]
|
||||
|
||||
for field in important_fields:
|
||||
val = device_data.get(field, 'MISSING')
|
||||
print(f' {field}: {val}')
|
||||
else:
|
||||
print(f'Error Response: {response.text}')
|
||||
|
||||
except Exception as e:
|
||||
print(f'Request failed: {e}')
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_device_lookup()
|
||||
21
tsconfig.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"module": "CommonJS",
|
||||
"lib": ["ESNext", "DOM"],
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"moduleResolution": "node",
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"sourceMap": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@shared/*": ["src/shared/*"]
|
||||
}
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||