feat: terminal, eventbus, load recipe
- change: disable reboot android when logged out - change: load recipe from android app's memory (requires ^0.0.3) - fix: adb payload handler may get incomplete message Signed-off-by: pakintada@gmail.com <Pakin>
This commit is contained in:
parent
ea7ec00b4b
commit
d4eb3be886
17 changed files with 2415 additions and 42 deletions
|
|
@ -7,16 +7,40 @@ import {
|
|||
} from '../services/androidRecipeExportService';
|
||||
import { handleIncomingMessages } from './messageHandler';
|
||||
import { setMenuSaved, setMenuSaveError } from '../stores/menuSaveStore';
|
||||
import { recipeFromMachineQuery } from '../stores/recipeStore';
|
||||
import { recipeFromMachine, recipeFromMachineQuery } from '../stores/recipeStore';
|
||||
import { buildTags, getMenuStatus } from '$lib/data/recipeService';
|
||||
import * as semver from 'semver';
|
||||
import { env } from '$env/dynamic/public';
|
||||
import { getContext } from 'svelte';
|
||||
import { GlobalEventBus, useEventBus } from '../utils/eventBus';
|
||||
|
||||
type AdbPayload = { type: string; payload: any };
|
||||
|
||||
let queuedPromises = new Array<Promise<void>>();
|
||||
|
||||
async function handleAdbPayload(raw_payload: string) {
|
||||
console.log('[ADB] Received payload:', raw_payload.slice(0, 300));
|
||||
// console.log('[ADB] Received payload:', raw_payload.slice(0, 300));
|
||||
const APP_VERSION = env.PUBLIC_APP_SEMVER;
|
||||
// const bus = useEventBus();
|
||||
|
||||
try {
|
||||
const payload: AdbPayload = JSON.parse(raw_payload);
|
||||
console.log('[ADB] Parsed type:', payload.type, 'payload:', payload.payload);
|
||||
switch (payload.type) {
|
||||
// console.log('[ADB] Parsed type:', payload.type, 'payload:', payload.payload);
|
||||
|
||||
// Emit payload event for terminal drawer payload viewer
|
||||
GlobalEventBus.emit('adb:payload', payload);
|
||||
|
||||
let payload_type = payload.type;
|
||||
let sub_type = null;
|
||||
// sub type handler
|
||||
if (payload_type.includes('/')) {
|
||||
//
|
||||
let tspl = payload_type.split('/');
|
||||
payload_type = tspl[0];
|
||||
sub_type = tspl[1];
|
||||
}
|
||||
|
||||
switch (payload_type) {
|
||||
case 'log':
|
||||
let log_level = payload.payload['level'] ?? 'INFO';
|
||||
let log_message = payload.payload['msg'] ?? '';
|
||||
|
|
@ -162,10 +186,177 @@ async function handleAdbPayload(raw_payload: string) {
|
|||
addNotification(`ERR:${error?.message ?? 'Unable to load recipe export from Android'}`)
|
||||
);
|
||||
break;
|
||||
case 'get-recipe-response':
|
||||
// only update recipe from memory of brew app
|
||||
if (!semver.satisfies(APP_VERSION, '^0.0.3')) {
|
||||
// reject
|
||||
console.log('unsupported version');
|
||||
break;
|
||||
}
|
||||
|
||||
let stream_recipe_idx = -1;
|
||||
|
||||
try {
|
||||
stream_recipe_idx = parseInt(sub_type ?? '-1');
|
||||
} catch (_) {}
|
||||
|
||||
if (stream_recipe_idx > -1) {
|
||||
// TODO: update both recipeFromMachine and recipeFromMachineQuery
|
||||
//
|
||||
|
||||
queuedPromises.push(
|
||||
new Promise((resolve, reject) => {
|
||||
let recipeRawFromMachine = get(recipeFromMachine);
|
||||
let recipeMachineQ = get(recipeFromMachineQuery);
|
||||
|
||||
if (!Object.keys(recipeMachineQ).includes('recipe')) {
|
||||
recipeMachineQ = {
|
||||
...recipeMachineQ,
|
||||
recipe: {}
|
||||
};
|
||||
}
|
||||
|
||||
let current_r01_query = recipeMachineQ.recipe;
|
||||
|
||||
let rp_from_payload = JSON.parse(payload.payload);
|
||||
|
||||
try {
|
||||
if (
|
||||
recipeRawFromMachine != null &&
|
||||
Object.keys(recipeRawFromMachine).includes('Recipe01')
|
||||
) {
|
||||
let is_update = false;
|
||||
// update, assume that we already fetch
|
||||
for (let rp of recipeRawFromMachine['Recipe01']) {
|
||||
if (rp['productCode'] == rp_from_payload['productCode']) {
|
||||
rp = rp_from_payload;
|
||||
is_update = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// new menu
|
||||
if (!is_update) recipeRawFromMachine['Recipe01'].push(rp_from_payload);
|
||||
} else {
|
||||
// not initialize
|
||||
recipeRawFromMachine = {
|
||||
Recipe01: [rp_from_payload]
|
||||
};
|
||||
}
|
||||
|
||||
// build as overview style compatible
|
||||
|
||||
let overview_menu = {
|
||||
productCode: rp_from_payload['productCode'] ?? '<not set>',
|
||||
name: rp_from_payload['name']
|
||||
? rp_from_payload['name']
|
||||
: (rp_from_payload['otherName'] ?? '<not set>'),
|
||||
description: rp_from_payload['desciption']
|
||||
? rp_from_payload['desciption']
|
||||
: (rp_from_payload['otherDescription'] ?? '<not set>'),
|
||||
tags: buildTags(rp_from_payload),
|
||||
status: getMenuStatus(rp_from_payload['MenuStatus'])
|
||||
};
|
||||
|
||||
current_r01_query[overview_menu.productCode] = overview_menu;
|
||||
|
||||
recipeMachineQ = {
|
||||
...recipeMachineQ,
|
||||
recipe: current_r01_query
|
||||
};
|
||||
|
||||
recipeFromMachineQuery.set(recipeMachineQ);
|
||||
recipeFromMachine.set(recipeRawFromMachine);
|
||||
|
||||
if (stream_recipe_idx == 0) {
|
||||
addNotification(`INFO:Loading recipes ...`);
|
||||
}
|
||||
|
||||
resolve();
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
})
|
||||
);
|
||||
} else if (sub_type == 'end' && payload.payload.includes('finish')) {
|
||||
let force_reload = payload.payload.includes('reload');
|
||||
|
||||
console.log('queued recipes: ', queuedPromises.length);
|
||||
if (queuedPromises.length > 0) {
|
||||
try {
|
||||
await Promise.all(queuedPromises);
|
||||
console.log('clear all recipe promises');
|
||||
queuedPromises = new Array();
|
||||
|
||||
GlobalEventBus.emitUntilConsumed('recipe-event', {
|
||||
type: 'load-recipe',
|
||||
status: 'end',
|
||||
reload: force_reload
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('some promise failed: ', e);
|
||||
|
||||
GlobalEventBus.emitUntilConsumed('recipe-event', {
|
||||
type: 'load-recipe-fail',
|
||||
status: 'end',
|
||||
reload: force_reload
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if (sub_type?.startsWith('mat')) {
|
||||
let recipeRawFromMachine = get(recipeFromMachine);
|
||||
|
||||
if (sub_type == 'mat-0') {
|
||||
addNotification('INFO:Loading materials ...');
|
||||
}
|
||||
|
||||
if (
|
||||
recipeRawFromMachine != null &&
|
||||
Object.keys(recipeRawFromMachine).includes('MaterialSetting')
|
||||
) {
|
||||
recipeRawFromMachine.MaterialSetting.push(JSON.parse(payload.payload));
|
||||
} else {
|
||||
// not has field material yet
|
||||
recipeRawFromMachine = {
|
||||
...recipeRawFromMachine,
|
||||
MaterialSetting: [JSON.parse(payload.payload)]
|
||||
};
|
||||
}
|
||||
|
||||
console.log('checking add mat', recipeRawFromMachine);
|
||||
recipeFromMachine.set(recipeRawFromMachine);
|
||||
} else if (sub_type == 'toppings') {
|
||||
let recipeRawFromMachine = get(recipeFromMachine);
|
||||
|
||||
let topping_raw = JSON.parse(payload.payload);
|
||||
console.log('receive topping', topping_raw);
|
||||
|
||||
//
|
||||
recipeRawFromMachine = {
|
||||
...recipeRawFromMachine,
|
||||
Topping: topping_raw
|
||||
};
|
||||
|
||||
// materialFromMachineQuery
|
||||
|
||||
addNotification('INFO:Loading toppings ...');
|
||||
|
||||
recipeFromMachine.set(recipeRawFromMachine);
|
||||
} else {
|
||||
// unhandled sub type
|
||||
console.log('unhandled sub type', payload);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
}
|
||||
} catch (error: any) {
|
||||
// invalid format
|
||||
// invalid format — emit error event so listeners (e.g. terminal) can react
|
||||
GlobalEventBus.emit('adb:payload-error', {
|
||||
raw_payload,
|
||||
error: error?.message ?? 'Unknown parse error',
|
||||
timestamp: new Date().toISOString()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue