feat: showing recipe list values

- add displaying for values in recipe list, with some editable fields except topping, string params, feed pattern/level

Signed-off-by: pakintada@gmail.com <Pakin>
This commit is contained in:
pakintada@gmail.com 2026-03-04 13:28:14 +07:00
parent 4866674f26
commit dbb5ce466c
14 changed files with 640 additions and 37 deletions

View file

@ -244,7 +244,7 @@
connectionButtonVariant = 'default';
connectDeviceOk = false;
}
connectionButtonDisable = false;
// connectionButtonDisable = false;
}
async function checkStoredCredentials() {
@ -336,7 +336,7 @@
onMount(async () => {
await checkStoredCredentials();
await tryAutoConnect();
if (!connectDeviceOk && !adb.getAdbInstance()) await tryAutoConnect();
});
</script>

View file

@ -21,6 +21,7 @@ import RecipelistValue from './recipelist-value.svelte';
import { DragHandle } from './recipelist-table.svelte';
import { createRawSnippet } from 'svelte';
import RecipelistMatSelect from './recipelist-mat-select.svelte';
import { recipeDataEvent } from '$lib/core/stores/recipeStore';
export type RecipelistMaterial = {
id: number;
@ -29,6 +30,7 @@ export type RecipelistMaterial = {
values: {
string_param: string;
mix_order: number;
stir_time: number;
feed: {
pattern: number;
parameter: number;
@ -69,12 +71,6 @@ export const columns: ColumnDef<RecipelistMaterial>[] = [
{
accessorKey: 'is_use',
id: 'is_use',
header: ({ column }) =>
renderSnippet(
createRawSnippet(() => ({
render: () => '<div class="w-0.5">Enable</div>'
}))
),
cell: ({ row }) => {
return renderComponent(RecipelistIsuse, {
checked: row.original.is_use,
@ -96,6 +92,11 @@ export const columns: ColumnDef<RecipelistMaterial>[] = [
onMatChange: (value: any) => {
row.original.material_id = value;
console.log('change mat', value);
recipeDataEvent.set({
event_type: 'mat_change',
payload: value,
index: row.original.id
});
row.toggleSelected(row.original.is_use);
}
});
@ -107,6 +108,17 @@ export const columns: ColumnDef<RecipelistMaterial>[] = [
header: ({ column }) => 'Values',
cell: ({ row }) => {
return renderComponent(RecipelistValue, {
row_uid: row.original.id,
mat_id: row.original.material_id,
onEditValue: (changes: any) => {
// get change parameters
},
onDetectMixOrder: () => {
// set next
},
onDetectToppingSlot: () => {
// replace display mat with topping name
},
...row.original.values
});
}

View file

@ -8,7 +8,11 @@
import { columns, type RecipelistMaterial } from './columns';
import { get, readable, writable } from 'svelte/store';
import { materialFromMachineQuery, materialFromServerQuery } from '$lib/core/stores/recipeStore';
import {
latestRecipeToppingData,
materialFromMachineQuery,
materialFromServerQuery
} from '$lib/core/stores/recipeStore';
import { generateIcing } from '$lib/helpers/icingGen';
import { machineInfoStore } from '$lib/core/stores/machineInfoStore';
import MachineInfo from '../machine-info.svelte';
@ -29,18 +33,17 @@
let recipeListMatState: RecipelistMaterial[] = $state([]);
let recipeListOriginal: RecipelistMaterial[] = $state([]);
let toppingSlotState: any = $state([]);
function remappingToColumn(data: any[]): RecipelistMaterial[] {
let ret: RecipelistMaterial[] = [];
// expect recipelist
if (materialSnapshot) {
let d_cnt = 0;
for (let rpl of data) {
let mat =
refPage == 'brew'
? materialSnapshot.filter(
(x: any) => x['id'].toString() === rpl['materialPathId'].toString()
)[0]
: materialSnapshot[rpl['materialPathId']];
let mat = materialSnapshot.filter(
(x: any) => x['id'].toString() === rpl['materialPathId'].toString()
)[0];
// console.log('mat filter get', Object(mat), Object.keys(mat));
@ -61,9 +64,10 @@
values: {
string_param: rpl['StringParam'],
mix_order: rpl['MixOrder'],
stir_time: rpl['stirTime'],
feed: {
pattern: rpl['feedPattern'],
parameter: rpl['feedParameter']
pattern: rpl['FeedPattern'],
parameter: rpl['FeedParameter']
},
powder: {
gram: rpl['powderGram'],
@ -113,9 +117,11 @@
materialSnapshot = get(materialFromMachineQuery);
}
console.log(`detail : ${JSON.stringify(recipeData)}`);
recipeListMatState = remappingToColumn(recipeData['recipes']);
toppingSlotState = recipeData['ToppingSet'];
latestRecipeToppingData.set(toppingSlotState);
// save old value\
}
});

View file

@ -4,7 +4,7 @@
import * as DropdownMenu from '$lib/components/ui/dropdown-menu/index';
import { get } from 'svelte/store';
import {
materialData,
materialFromServerQuery,
materialFromMachineQuery,
referenceFromPage
} from '$lib/core/stores/recipeStore';
@ -26,7 +26,9 @@
onMount(() => {
refPage = get(referenceFromPage);
if (refPage === 'brew') allMatData = get(materialFromMachineQuery);
else if (refPage === 'overview') allMatData = get(materialData);
else if (refPage === 'overview') allMatData = get(materialFromServerQuery);
// console.log('all mat data', JSON.stringify(allMatData));
});
</script>

View file

@ -105,7 +105,7 @@
<Card.Root>
<Card.Header>
<Card.Title>Recipe List</Card.Title>
<Card.Description>Material used in this menu's brewing process</Card.Description>
<Card.Description>Material used in this menu's brewing process.</Card.Description>
<Card.Content>
<!-- table -->

View file

@ -1,6 +1,360 @@
<script lang="ts">
import { onDestroy, onMount } from 'svelte';
import type { RecipelistMaterial } from './columns';
import {
convertFromInterProductCode,
extractMaterialIdFromDisplay,
getMaterialType
} from '$lib/data/recipeService';
import Label from '../ui/label/label.svelte';
import Input from '../ui/input/input.svelte';
import Separator from '$lib/components/ui/separator/separator.svelte';
import Button from '../ui/button/button.svelte';
import { PencilIcon } from '@lucide/svelte/icons';
import * as Tooltip from '../ui/tooltip/index';
import {
latestRecipeToppingData,
recipeDataEvent,
toppingGroupFromServerQuery,
toppingListFromServerQuery
} from '$lib/core/stores/recipeStore';
import { get } from 'svelte/store';
let { string_param, mix_order, feed, water, powder, syrup }: RecipelistMaterial['values'] =
$props();
let {
row_uid,
mat_id,
onDetectToppingSlot,
onDetectMixOrder,
onEditValue,
string_param,
mix_order,
feed,
water,
powder,
syrup,
stir_time
}: {
row_uid: number;
mat_id: string;
onDetectToppingSlot: any;
onDetectMixOrder: any;
onEditValue: any;
} & RecipelistMaterial['values'] = $props();
let currentMaterialType = $state('');
let hasMixOrder = $state(false);
let currentStringParams: any = $state({});
let currentMaterialInt: number = $state(0);
// All ui states
let showBlenderParam = $state(false);
let showMixParam = $state(false);
let showSyrupParam = $state(false);
let showWaterParam = $state(false);
let showPowderParam = $state(false);
let showIceParam = $state(false);
let showAdjustGrinder = $state(false);
let showEspressoParam = $state(false);
let showToppingIdx = $state(false);
let showEquipmentLayout = $state(false);
let showToppingParam = $state(false);
let showSubtractPreWater = $state(false);
let showCleanOptionParam = $state(false);
// toppings
let currentToppings: any = $state([]);
// current topping of this row
let currentToppingInRow: any = $state();
let selectableToppingInGroup: any[] = $state([]);
let unsubRecipeDataEvent: any;
function isToppingId(mat_id: string): boolean {
let mat_num = extractMaterialIdFromDisplay(mat_id);
currentMaterialInt = mat_num;
return mat_num > 8110 && mat_num < 8131;
}
function getToppingSlot() {
return currentMaterialInt - 8110 - 1;
}
function extractStringParam() {
if (string_param && string_param !== '') {
let plist = string_param.split(',');
for (let param of plist) {
if (param !== '') {
let kv = param.split('=');
let key = kv[0];
let value = kv[1] ?? '';
console.log('key', key, 'value', value);
currentStringParams[key] = value;
}
}
}
}
function getPowderSyrupValue() {
if (currentMaterialType === 'powder' || currentMaterialType === 'bean') {
return powder.gram;
} else if (currentMaterialType === 'syrup') {
return syrup.gram;
}
return 0;
}
function getStirTimeName() {
switch (currentMaterialType) {
case 'whipper':
return 'Mix';
case 'bean':
return 'Grinder';
case 'others':
if (currentMaterialInt == 8001 || currentMaterialInt == 8002) {
return 'Clean';
}
default:
return '';
}
}
function getToppingDisplay() {
let current_row_topping = currentToppings[getToppingSlot()];
let groupQuery = get(toppingGroupFromServerQuery);
let listQuery = get(toppingListFromServerQuery);
// console.log(JSON.stringify(groupQuery[0]));
// console.log(JSON.stringify(listQuery[0]));
let groupData = groupQuery.find(
(x: any) => x.groupID.toString() === current_row_topping['groupID']
);
let listData = listQuery.filter(
(x: any) =>
groupData &&
Object.keys(groupData).includes('idInGroup') &&
groupData['idInGroup'].split(',').includes(x.id.toString())
);
console.log('topping data', JSON.stringify(groupData), 'list', listData.length);
currentToppingInRow =
current_row_topping['groupID'] === 0 || current_row_topping['groupID'] === '0'
? {
name: 'Empty',
otherName: 'Empty',
id: 0
}
: groupData;
selectableToppingInGroup =
currentToppingInRow.id === 0
? [
{
name: 'Empty',
otherName: 'Empty',
id: 0
}
]
: listData;
}
function getCurrentSelectedToppingGroup() {
if (currentToppingInRow) {
return currentToppingInRow['otherName'] ?? currentToppingInRow['name'];
} else {
return 'Unknown';
}
}
function getCurrentSelectedToppingList() {
let current_selected = selectableToppingInGroup.find(
(x) => x.id === currentToppings[getToppingSlot()]['ListGroupID'][0]
);
if (currentToppings[getToppingSlot()]['ListGroupID'][0] === 0) {
return 'Empty';
}
if (!current_selected) {
return 'Unknown';
}
return current_selected.otherName ?? current_selected.name;
}
function initialize() {
currentToppings = get(latestRecipeToppingData);
hasMixOrder = mix_order == 1;
extractStringParam();
if (isToppingId(mat_id) && onDetectToppingSlot) {
currentMaterialType = 'topping';
getToppingDisplay();
onDetectToppingSlot();
} else {
let mat_num = extractMaterialIdFromDisplay(mat_id);
currentMaterialInt = mat_num;
let mat_type_t1 = getMaterialType(mat_num);
let mat_type_t2 = getMaterialType(convertFromInterProductCode(mat_num));
// console.log('type get', mat_type_t1, mat_type_t2);
currentMaterialType = mat_type_t1 === mat_type_t2 ? mat_type_t1 : mat_type_t2;
if (hasMixOrder) {
console.log('detect mix order', mat_num);
}
if (feed.parameter > 0 || feed.pattern > 0) {
console.log('has feed fields', JSON.stringify(feed));
}
}
}
function handleEvents(event: { event_type: string; payload: any; index: number | undefined }) {
console.log('triggered event', event.event_type, JSON.stringify(event.payload));
if (event.event_type === 'mat_change') {
// update value, do re-render
initialize();
}
}
function triggerEditChange(value: any) {
console.log('triggered on change editing', JSON.stringify(value));
}
onMount(() => {
initialize();
unsubRecipeDataEvent = recipeDataEvent.subscribe((event) => {
if (event && event.index && event.index === row_uid) {
// has some event
handleEvents(event);
}
});
});
onDestroy(() => {
if (unsubRecipeDataEvent) {
unsubRecipeDataEvent();
}
});
</script>
{#if currentMaterialType === 'topping'}
<!-- do topping layout -->
<div>
<!-- get name of topping -->
<div class="mx-auto my-4 flex flex-row gap-8">
<!-- popup selector for topping group -->
<Button variant="default">{getCurrentSelectedToppingGroup()}</Button>
<!-- popup selector for topping list -->
<Button variant="default">{getCurrentSelectedToppingList()}</Button>
</div>
</div>
{:else}
<div>
<div class="flex w-full flex-row gap-4">
<!-- string param -->
{#if !hasMixOrder}
<!-- check if param is esp-v2-press-value -->
{#if currentStringParams['esp-v2-press-value']}
<div class="space-y-1">
<Label class="font-bold" for={`esp_v2_press_${row_uid}`}>Press</Label>
<div class="flex flex-row items-center space-x-2 text-center">
<Input
class="w-16"
id={`esp_v2_press_${row_uid}`}
type="number"
value={currentStringParams['esp-v2-press-value']}
onchangecapture={(v) =>
triggerEditChange(`${v.currentTarget.id}=${v.currentTarget.value}`)}
/>
<p>mA</p>
</div>
</div>
{/if}
{#if water.yield > 0}
<div class="space-y-1">
<Label class="font-bold" for={`water_yield_volume_${row_uid}`}>Hot</Label>
<div class="flex flex-row items-center space-x-2 text-center">
<Input
class="w-16"
type="number"
id={`water_yield_volume_${row_uid}`}
value={water.yield}
onchangecapture={(v) =>
triggerEditChange(`${v.currentTarget.id}=${v.currentTarget.value}`)}
/>
<p>ml</p>
</div>
</div>
{/if}
{#if water.cold > 0}
<div class="space-y-1">
<Label class="font-bold" for={`water_cold_volume_${row_uid}`}>Cold</Label>
<div class="flex flex-row items-center space-x-2 text-center">
<Input
class="w-16"
type="number"
id={`water_cold_volume_${row_uid}`}
value={water.cold}
onchangecapture={(v) =>
triggerEditChange(`${v.currentTarget.id}=${v.currentTarget.value}`)}
/>
<p>ml</p>
</div>
</div>
{/if}
{#if currentMaterialType !== 'cup' && currentMaterialType !== 'topping' && stir_time > 0}
<div class="space-y-1">
<Label class="font-bold" for={`stir_time_${row_uid}`}>{getStirTimeName()}</Label>
<div class="flex flex-row items-center space-x-2 text-center">
<Input
class="w-16"
type="number"
id={`stir_time_${row_uid}`}
value={stir_time / 10}
onchangecapture={(v) =>
triggerEditChange(`${v.currentTarget.id}=${v.currentTarget.value}`)}
/>
<p>sec</p>
</div>
</div>
{/if}
{/if}
<!-- display powder/syrup -->
{#if currentMaterialType === 'syrup' || currentMaterialType === 'powder' || currentMaterialType === 'bean'}
<div class="space-y-1">
<Label class="font-bold" for={`powder_syrup_volume_${row_uid}`}>Volume</Label>
<div class="flex flex-row items-center space-x-2 text-center">
<Input
class="w-16"
type="number"
id={`powder_syrup_volume_${row_uid}`}
value={getPowderSyrupValue()}
onchangecapture={(v) =>
triggerEditChange(`${v.currentTarget.id}=${v.currentTarget.value}`)}
/>
<p>gram</p>
</div>
</div>
{/if}
</div>
<!-- feed pattern -->
{#if feed.parameter > 0 || feed.pattern > 0}
<div class="mx-auto my-4 flex items-center gap-8 text-center">
<Button variant="outline">Style {feed.pattern}</Button>
<Button variant="outline">Level {feed.parameter}</Button>
</div>
{/if}
</div>
{/if}

View file

@ -76,7 +76,7 @@
let recipe01Snap = recipeServerSnapshot['recipe'];
if (recipe01Snap) {
currentData = recipe01Snap[productCode] ?? {};
console.log(`current data : ${JSON.stringify(Object.keys(recipe01Snap))}`);
// console.log(`current data : ${JSON.stringify(Object.keys(recipe01Snap))}`);
if (currentData.MenuStatus) {
currentMenuStatus = matchMenuStatus(currentData.MenuStatus);
}
@ -87,7 +87,9 @@
{#if isDesktop.current}
<Dialog.Root bind:open>
<Dialog.Trigger onselect={(e) => e.preventDefault()}>View</Dialog.Trigger>
<Dialog.Trigger class="w-full text-start" onselect={(e) => e.preventDefault()}
>View</Dialog.Trigger
>
<Dialog.Content class="sm:max-w-3/4">
<Dialog.Header>
<Dialog.Title>Edit Recipe {productCode}</Dialog.Title>

View file

@ -6,7 +6,9 @@ import {
recipeDataError,
recipeLoading,
recipeOverviewData,
recipeStreamMeta
recipeStreamMeta,
toppingGroupFromServerQuery,
toppingListFromServerQuery
} from '../stores/recipeStore';
import { buildOverviewFromServer } from '$lib/data/recipeService';
import { auth } from '../client/firebase';
@ -103,18 +105,48 @@ const handlers: Record<string, (payload: any) => void> = {
// know type
switch (extp) {
case 'matset':
let curr_mat_query = get(materialFromServerQuery);
let curr_mat_query = get(materialFromServerQuery) ?? [];
if (!curr_mat_query) {
curr_mat_query = [];
}
// ex_payload has chunks of material setting
for (let m of ex_payload) {
let mid = m.id;
curr_mat_query[mid] = m;
// curr_mat_query[mid] = m;
curr_mat_query.push(m);
}
// console.log('current materials: ', JSON.stringify(curr_mat_query));
materialFromServerQuery.set(curr_mat_query);
break;
case 'topplist':
let curr_topping_list_query = get(toppingListFromServerQuery) ?? [];
if (!curr_topping_list_query) {
curr_topping_list_query = [];
}
for (let t of ex_payload) {
curr_topping_list_query.push(t);
}
toppingListFromServerQuery.set(curr_topping_list_query);
break;
case 'toppgrp':
let curr_topping_group_query = get(toppingGroupFromServerQuery) ?? [];
if (!curr_topping_group_query) {
curr_topping_group_query = [];
}
for (let t of ex_payload) {
curr_topping_group_query.push(t);
}
toppingGroupFromServerQuery.set(curr_topping_group_query);
break;
}
}

View file

@ -16,7 +16,7 @@ export function sendMessage(msg: OutMessage): boolean {
currentQueue.push(data);
queue.set(currentQueue);
addNotification('WARN:Queuing overview view request');
addNotification('WARN:Queuing request');
return false;
}

View file

@ -22,7 +22,19 @@ export const recipeFromMachineLoading = writable(false);
export const recipeFromMachineError = writable<string | null>(null);
export const recipeFromServerQuery = writable<any>({});
export const materialFromServerQuery = writable<any>({});
export const materialFromServerQuery = writable<any>([]);
export const toppingListFromServerQuery = writable<any>([]);
export const toppingGroupFromServerQuery = writable<any>([]);
// latest recipe data (use for interacting)
export const latestRecipeToppingData = writable<any>([]);
// edit data update
export const recipeDataEvent = writable<{
event_type: string;
payload: any;
index: number | undefined;
} | null>(null);
// NOTE: must not have any nested structures
// { recipe: {}, materials: {}, toppings: { groups: {}, lists: {} } }

View file

@ -137,4 +137,137 @@ function buildOverviewFromServer() {
}
}
export { buildOverviewFromServer };
const rangeMaterialMapping: { [key: string]: (id: number) => boolean } = {
soda: (id: number) => id == 1031,
water: (id: number) => id == 1,
ice: (id: number) => id == 9100,
whipper: (id: number) => id == 8102,
bean: (id: number) => inRange(1001, 1009, id) || inRange(1100, 1199, id),
leaves: (id: number) => inRange(1600, 1799, id),
syrup: (id: number) =>
inRange(1032, 1039, id) || inRange(1020, 1030, id) || inRange(1200, 1299, id),
powder: (id: number) => inRange(1040, 1080, id) || inRange(1300, 1399, id),
cup: (id: number) => inRange(9500, 9549, id),
lid: (id: number) => inRange(9600, 9649, id),
straw: (id: number) => inRange(9700, 9749, id),
icecream: (id: number) => inRange(2100, 2200, id),
topping: (id: number) => inRange(8110, 8130, id)
};
function inRange(min: number, max: number, value: number) {
// console.log(min, max, value, value >= min && value <= max);
return value >= min && value <= max;
}
function getCategories() {
let keys = Object.keys(rangeMaterialMapping);
keys.push('equipment');
return keys;
}
function getMaterialType(materialId: number) {
for (const key of Object.keys(rangeMaterialMapping)) {
if (rangeMaterialMapping[key](materialId)) {
return key;
}
}
return 'others';
}
function isNonMaterial(materialId: number) {
// test cup, lid, straw
return (
rangeMaterialMapping['cup'](materialId) ||
rangeMaterialMapping['lid'](materialId) ||
rangeMaterialMapping['straw'](materialId) ||
rangeMaterialMapping['whipper'](materialId) ||
rangeMaterialMapping['ice'](materialId)
);
}
const MATERIAL_INTER_GUARD = 300000;
// Inter mode checker
function convertFromInterProductCode(materialId: number) {
if (materialId > MATERIAL_INTER_GUARD) {
try {
let pure_id = materialId.toString().slice(2);
return parseInt(pure_id);
} catch (e) {}
}
return materialId;
}
// Extract material id from display
function extractMaterialIdFromDisplay(material_id: string): number {
// console.log('extracting from ', material_id);
let mat_split = material_id.split(' ');
let pure_mat_id = mat_split[mat_split.length - 1] ?? '0';
try {
// console.log('pure mat', pure_mat_id);
let mat_id_int = parseInt(pure_mat_id.replace('(', '').replace(')', '').trim());
return mat_id_int;
} catch (ignored) {}
return -1;
}
// StringParam
class StringParam {
StringParam: string;
extractedParams: { [key: string]: any } = {};
constructor(StringParam: string) {
this.StringParam = StringParam;
}
extract() {
// split by ,
const params = this.StringParam.split(',');
for (const param of params) {
const [key, value] = param.split('=');
if (key != '') {
this.extractedParams[key] = value;
}
}
return this;
}
as_list() {
let res: { pkey: string; pvalue: any }[] = [];
// iter through param
for (let p of Object.keys(this.extractedParams)) {
res.push({
pkey: p,
pvalue: this.extractedParams[p]
});
}
return res;
}
}
const stringParamsDefinition: { [key: string]: string } = {
'esp-v2-press-value': 'Current 100 x mA ( 10 - 24 )'
};
const conditionTests: { [key: string]: (arg: any) => boolean } = {
'not-zero': (arg: any) => arg != 0,
zero: (arg: any) => arg == 0,
'false-if-another-exist': (arg: any) => arg[1] != undefined
};
export {
buildOverviewFromServer,
StringParam,
convertFromInterProductCode,
getMaterialType,
getCategories,
isNonMaterial,
extractMaterialIdFromDisplay
};

View file

@ -11,14 +11,56 @@
import { auth } from '$lib/core/stores/auth';
import { get } from 'svelte/store';
import { connectToWebsocket } from '$lib/core/stores/websocketStore';
import * as adb from '$lib/core/adb/adb';
import { addNotification } from '$lib/core/stores/noti';
import { AdbDaemonWebUsbDeviceManager } from '@yume-chan/adb-daemon-webusb';
import AdbWebCredentialStore from '@yume-chan/adb-credential-web';
import { deviceCredentialManager } from '$lib/core/adb/deviceCredManager';
let { children } = $props();
onMount(() => {
async function tryAutoConnect() {
try {
if (!('usb' in navigator) || !AdbDaemonWebUsbDeviceManager.BROWSER) {
throw new Error('WebUSB not supported, try using fallback or different browser');
}
const devices = await AdbDaemonWebUsbDeviceManager.BROWSER.getDevices();
if (!devices || devices.length == 0) {
throw new Error('No device found');
}
if (devices.length > 1) {
throw new Error('Too many connected devices');
}
const device = devices[0];
const credStore = new AdbWebCredentialStore();
try {
await adb.connectDeviceByCred(device, credStore);
return true;
} catch (e: any) {
if (e.message === 'CREDENTIAL_EXPIRED') {
try {
await deviceCredentialManager.clearAllCredentials();
} catch (ignored) {}
}
return false;
}
} catch (e) {
console.error('error on auto connect brew page', e);
addNotification('ERROR:Failed to auto connect, please try again');
}
}
onMount(async () => {
let currentUser = get(auth);
console.log(`on mount layout current user: ${JSON.stringify(currentUser)}`);
// console.log(`on mount layout current user: ${JSON.stringify(currentUser)}`);
if (currentUser) {
connectToWebsocket();
await tryAutoConnect();
}
});
</script>

View file

@ -21,6 +21,7 @@
import { AdbDaemonWebUsbDeviceManager } from '@yume-chan/adb-daemon-webusb';
import AdbWebCredentialStore from '@yume-chan/adb-credential-web';
import { deviceCredentialManager } from '$lib/core/adb/deviceCredManager';
import { afterNavigate } from '$app/navigation';
const sourceDir = '/sdcard/coffeevending';
@ -36,8 +37,11 @@
let instance = adb.getAdbInstance();
recipeFromMachineLoading.set(true);
referenceFromPage.set('brew');
console.log('check instance', instance);
if (instance) {
console.log('instance passed!');
let dev_recipe = await adb.pull(`${sourceDir}/cfg/recipe_branch_dev.json`);
// console.log('dev recipe ok', dev_recipe);
if (dev_recipe) {
if (dev_recipe.length == 0) {
// case error, do last retry
@ -158,9 +162,7 @@
}
}
onMount(async () => {
// do auto connect
if (!adb.getAdbInstance()) await tryAutoConnect();
afterNavigate(async () => {
await startFetchRecipeFromMachine();
});

View file

@ -25,6 +25,7 @@
extractCookieOnNonBrowser,
setCookieOnNonBrowser
} from '$lib/helpers/cookie';
import { connectToWebsocket } from '$lib/core/stores/websocketStore';
let { children } = $props();
@ -48,6 +49,11 @@
});
return authStore.subscribe(async function (user) {
// console.log(`store get ${JSON.stringify(user)}`);
if (user != null) {
connectToWebsocket();
}
// reloading permissions
if (get(currentPermissions).length == 0 && user != null) {
// need update