Partially updated camera_test

Updated plot
This commit is contained in:
Knyffen 2024-09-17 18:40:12 +02:00
parent 8b7ba7ecc1
commit bb13d718aa
11 changed files with 285 additions and 267 deletions

BIN
assets/searchicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 860 B

View File

@ -20,7 +20,7 @@ console_error_panic_hook = { version = "0.1.7", optional = true }
rxing = "0.6.1"
image = "0.25.2"
web-sys = { version = "0.3.70", features = ["Navigator", "MediaDevices", "Document", "HtmlCanvasElement", "CanvasRenderingContext2d", "VideoFrame", "HtmlVideoElement", "ImageData", "Window", "HtmlInputElement", "HtmlButtonElement", "MediaStreamConstraints", "MediaStream", "HtmlMediaElement", "console", "EventTarget", "Request", "RequestInit", "RequestMode", "Response", "Headers", "NodeList", "Event", "DomTokenList", "Element", "FocusEvent"] }
web-sys = { version = "0.3.70", features = ["Navigator", "MediaDevices", "Document", "HtmlCanvasElement", "CanvasRenderingContext2d", "VideoFrame", "HtmlVideoElement", "ImageData", "Window", "HtmlInputElement", "HtmlButtonElement", "MediaStreamConstraints", "MediaStream", "HtmlMediaElement", "console", "EventTarget", "Request", "RequestInit", "RequestMode", "Response", "Headers", "NodeList", "Event", "DomTokenList", "Element", "FocusEvent", "NamedNodeMap", "Attr"] }
wasm-bindgen-futures = "0.4.43"
js-sys = "0.3.70"

View File

@ -27,8 +27,8 @@ export interface InitOutput {
readonly __wbindgen_malloc: (a: number, b: number) => number;
readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
readonly __wbindgen_export_2: WebAssembly.Table;
readonly _dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h74b50bd459e0fdd2: (a: number, b: number, c: number) => void;
readonly _dyn_core__ops__function__FnMut_____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__he6a2321bb6275149: (a: number, b: number) => void;
readonly _dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h3ee002e21c3855c9: (a: number, b: number, c: number) => void;
readonly _dyn_core__ops__function__FnMut_____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hda38a12a2a1c09dc: (a: number, b: number) => void;
readonly _dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__ha7dc131e1b42f45e: (a: number, b: number, c: number) => void;
readonly __wbindgen_add_to_stack_pointer: (a: number) => number;
readonly __wbindgen_free: (a: number, b: number, c: number) => void;

View File

@ -212,11 +212,11 @@ function makeMutClosure(arg0, arg1, dtor, f) {
return real;
}
function __wbg_adapter_36(arg0, arg1, arg2) {
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h74b50bd459e0fdd2(arg0, arg1, addHeapObject(arg2));
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h3ee002e21c3855c9(arg0, arg1, addHeapObject(arg2));
}
function __wbg_adapter_39(arg0, arg1) {
wasm._dyn_core__ops__function__FnMut_____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__he6a2321bb6275149(arg0, arg1);
wasm._dyn_core__ops__function__FnMut_____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hda38a12a2a1c09dc(arg0, arg1);
}
function __wbg_adapter_42(arg0, arg1, arg2) {
@ -275,7 +275,7 @@ function passArray8ToWasm0(arg, malloc) {
WASM_VECTOR_LEN = arg.length;
return ptr;
}
function __wbg_adapter_201(arg0, arg1, arg2, arg3) {
function __wbg_adapter_205(arg0, arg1, arg2, arg3) {
wasm.wasm_bindgen__convert__closures__invoke2_mut__h101e073056d1eef9(arg0, arg1, addHeapObject(arg2), addHeapObject(arg3));
}
@ -447,6 +447,10 @@ function __wbg_get_imports() {
const ret = getObject(arg0).classList;
return addHeapObject(ret);
};
imports.wbg.__wbg_attributes_ea6d5144381d1a6b = function(arg0) {
const ret = getObject(arg0).attributes;
return addHeapObject(ret);
};
imports.wbg.__wbg_setinnerHTML_ea7e3c6a3c4790c6 = function(arg0, arg1, arg2) {
getObject(arg0).innerHTML = getStringFromWasm0(arg1, arg2);
};
@ -477,6 +481,41 @@ function __wbg_get_imports() {
imports.wbg.__wbg_click_025eb185eb16f006 = function(arg0) {
getObject(arg0).click();
};
imports.wbg.__wbg_addEventListener_e167f012cbedfa4e = function() { return handleError(function (arg0, arg1, arg2, arg3) {
getObject(arg0).addEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3));
}, arguments) };
imports.wbg.__wbg_instanceof_HtmlButtonElement_998267b26d794a1e = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof HTMLButtonElement;
} catch (_) {
result = false;
}
const ret = result;
return ret;
};
imports.wbg.__wbg_getUserMedia_2f9c80e86991353a = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg0).getUserMedia(getObject(arg1));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_removeNamedItem_e56eae3d2c3fd505 = function() { return handleError(function (arg0, arg1, arg2) {
const ret = getObject(arg0).removeNamedItem(getStringFromWasm0(arg1, arg2));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_headers_7d46f181de2aa1dd = function(arg0) {
const ret = getObject(arg0).headers;
return addHeapObject(ret);
};
imports.wbg.__wbg_newwithstrandinit_a31c69e4cc337183 = function() { return handleError(function (arg0, arg1, arg2) {
const ret = new Request(getStringFromWasm0(arg0, arg1), getObject(arg2));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_setmethod_dc68a742c2db5c6a = function(arg0, arg1, arg2) {
getObject(arg0).method = getStringFromWasm0(arg1, arg2);
};
imports.wbg.__wbg_setmode_a781aae2bd3df202 = function(arg0, arg1) {
getObject(arg0).mode = ["same-origin","no-cors","cors","navigate",][arg1];
};
imports.wbg.__wbg_target_b7cb1739bee70928 = function(arg0) {
const ret = getObject(arg0).target;
return isLikeNone(ret) ? 0 : addHeapObject(ret);
@ -495,67 +534,13 @@ function __wbg_get_imports() {
const ret = getObject(arg0).relatedTarget;
return isLikeNone(ret) ? 0 : addHeapObject(ret);
};
imports.wbg.__wbg_instanceof_HtmlButtonElement_998267b26d794a1e = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof HTMLButtonElement;
} catch (_) {
result = false;
}
const ret = result;
return ret;
imports.wbg.__wbg_setsrcObject_8df760f949eb64ae = function(arg0, arg1) {
getObject(arg0).srcObject = getObject(arg1);
};
imports.wbg.__wbg_data_3748d6414e549999 = function(arg0, arg1) {
const ret = getObject(arg1).data;
const ptr1 = passArray8ToWasm0(ret, wasm.__wbindgen_malloc);
const len1 = WASM_VECTOR_LEN;
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
};
imports.wbg.__wbg_getUserMedia_2f9c80e86991353a = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg0).getUserMedia(getObject(arg1));
imports.wbg.__wbg_play_69733added0ad2db = function() { return handleError(function (arg0) {
const ret = getObject(arg0).play();
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_headers_7d46f181de2aa1dd = function(arg0) {
const ret = getObject(arg0).headers;
return addHeapObject(ret);
};
imports.wbg.__wbg_newwithstrandinit_a31c69e4cc337183 = function() { return handleError(function (arg0, arg1, arg2) {
const ret = new Request(getStringFromWasm0(arg0, arg1), getObject(arg2));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_setaudio_4463de95ab3f5403 = function(arg0, arg1) {
getObject(arg0).audio = getObject(arg1);
};
imports.wbg.__wbg_setvideo_595a02280294c105 = function(arg0, arg1) {
getObject(arg0).video = getObject(arg1);
};
imports.wbg.__wbg_addEventListener_e167f012cbedfa4e = function() { return handleError(function (arg0, arg1, arg2, arg3) {
getObject(arg0).addEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3));
}, arguments) };
imports.wbg.__wbg_set_b3c7c6d2e5e783d6 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
getObject(arg0).set(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
}, arguments) };
imports.wbg.__wbg_instanceof_HtmlCanvasElement_1a96a01603ec2d8b = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof HTMLCanvasElement;
} catch (_) {
result = false;
}
const ret = result;
return ret;
};
imports.wbg.__wbg_setwidth_e371a8d6b16ebe84 = function(arg0, arg1) {
getObject(arg0).width = arg1 >>> 0;
};
imports.wbg.__wbg_setheight_ba99ad2df4295e89 = function(arg0, arg1) {
getObject(arg0).height = arg1 >>> 0;
};
imports.wbg.__wbg_getContext_69ec873410cbba3c = function() { return handleError(function (arg0, arg1, arg2) {
const ret = getObject(arg0).getContext(getStringFromWasm0(arg1, arg2));
return isLikeNone(ret) ? 0 : addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_instanceof_HtmlVideoElement_cb7446c5ced3aafa = function(arg0) {
let result;
try {
@ -580,6 +565,54 @@ function __wbg_get_imports() {
const ret = getObject(arg0).videoHeight;
return ret;
};
imports.wbg.__wbg_set_b3c7c6d2e5e783d6 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
getObject(arg0).set(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
}, arguments) };
imports.wbg.__wbg_instanceof_HtmlCanvasElement_1a96a01603ec2d8b = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof HTMLCanvasElement;
} catch (_) {
result = false;
}
const ret = result;
return ret;
};
imports.wbg.__wbg_setwidth_e371a8d6b16ebe84 = function(arg0, arg1) {
getObject(arg0).width = arg1 >>> 0;
};
imports.wbg.__wbg_setheight_ba99ad2df4295e89 = function(arg0, arg1) {
getObject(arg0).height = arg1 >>> 0;
};
imports.wbg.__wbg_getContext_69ec873410cbba3c = function() { return handleError(function (arg0, arg1, arg2) {
const ret = getObject(arg0).getContext(getStringFromWasm0(arg1, arg2));
return isLikeNone(ret) ? 0 : addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_data_3748d6414e549999 = function(arg0, arg1) {
const ret = getObject(arg1).data;
const ptr1 = passArray8ToWasm0(ret, wasm.__wbindgen_malloc);
const len1 = WASM_VECTOR_LEN;
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
};
imports.wbg.__wbg_mediaDevices_faa6b252480b6169 = function() { return handleError(function (arg0) {
const ret = getObject(arg0).mediaDevices;
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_setaudio_4463de95ab3f5403 = function(arg0, arg1) {
getObject(arg0).audio = getObject(arg1);
};
imports.wbg.__wbg_setvideo_595a02280294c105 = function(arg0, arg1) {
getObject(arg0).video = getObject(arg1);
};
imports.wbg.__wbg_parentElement_fbf8d048e797326d = function(arg0) {
const ret = getObject(arg0).parentElement;
return isLikeNone(ret) ? 0 : addHeapObject(ret);
};
imports.wbg.__wbg_values_0b652fbd880b650d = function(arg0) {
const ret = getObject(arg0).values();
return addHeapObject(ret);
};
imports.wbg.__wbg_instanceof_Response_e91b7eb7c611a9ae = function(arg0) {
let result;
try {
@ -594,31 +627,6 @@ function __wbg_get_imports() {
const ret = getObject(arg0).json();
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_parentElement_fbf8d048e797326d = function(arg0) {
const ret = getObject(arg0).parentElement;
return isLikeNone(ret) ? 0 : addHeapObject(ret);
};
imports.wbg.__wbg_values_0b652fbd880b650d = function(arg0) {
const ret = getObject(arg0).values();
return addHeapObject(ret);
};
imports.wbg.__wbg_setmethod_dc68a742c2db5c6a = function(arg0, arg1, arg2) {
getObject(arg0).method = getStringFromWasm0(arg1, arg2);
};
imports.wbg.__wbg_setmode_a781aae2bd3df202 = function(arg0, arg1) {
getObject(arg0).mode = ["same-origin","no-cors","cors","navigate",][arg1];
};
imports.wbg.__wbg_setsrcObject_8df760f949eb64ae = function(arg0, arg1) {
getObject(arg0).srcObject = getObject(arg1);
};
imports.wbg.__wbg_play_69733added0ad2db = function() { return handleError(function (arg0) {
const ret = getObject(arg0).play();
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_mediaDevices_faa6b252480b6169 = function() { return handleError(function (arg0) {
const ret = getObject(arg0).mediaDevices;
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_instanceof_HtmlInputElement_88bf515ab1d9511d = function(arg0) {
let result;
try {
@ -775,7 +783,7 @@ function __wbg_get_imports() {
const a = state0.a;
state0.a = 0;
try {
return __wbg_adapter_201(a, state0.b, arg0, arg1);
return __wbg_adapter_205(a, state0.b, arg0, arg1);
} finally {
state0.a = a;
}
@ -845,16 +853,16 @@ function __wbg_get_imports() {
const ret = wasm.memory;
return addHeapObject(ret);
};
imports.wbg.__wbindgen_closure_wrapper176 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 31, __wbg_adapter_36);
imports.wbg.__wbindgen_closure_wrapper201 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 43, __wbg_adapter_36);
return addHeapObject(ret);
};
imports.wbg.__wbindgen_closure_wrapper177 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 31, __wbg_adapter_39);
imports.wbg.__wbindgen_closure_wrapper202 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 43, __wbg_adapter_39);
return addHeapObject(ret);
};
imports.wbg.__wbindgen_closure_wrapper1773 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 499, __wbg_adapter_42);
imports.wbg.__wbindgen_closure_wrapper1797 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 498, __wbg_adapter_42);
return addHeapObject(ret);
};

Binary file not shown.

View File

@ -8,8 +8,8 @@ export function enable_panic_debug(): void;
export function __wbindgen_malloc(a: number, b: number): number;
export function __wbindgen_realloc(a: number, b: number, c: number, d: number): number;
export const __wbindgen_export_2: WebAssembly.Table;
export function _dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h74b50bd459e0fdd2(a: number, b: number, c: number): void;
export function _dyn_core__ops__function__FnMut_____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__he6a2321bb6275149(a: number, b: number): void;
export function _dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h3ee002e21c3855c9(a: number, b: number, c: number): void;
export function _dyn_core__ops__function__FnMut_____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hda38a12a2a1c09dc(a: number, b: number): void;
export function _dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__ha7dc131e1b42f45e(a: number, b: number, c: number): void;
export function __wbindgen_add_to_stack_pointer(a: number): number;
export function __wbindgen_free(a: number, b: number, c: number): void;

View File

@ -11,14 +11,17 @@ use web_sys::*;
const CANVAS_WIDTH: u32 = 1920;
const CANVAS_HEIGHT: u32 = 1080;
const VIDEO_ID: &str = "video";
const VIDEO_CONTAINER_ID: &str = "video-container";
const CANVAS_ID: &str = "canvas";
const BARCODE_ID: &str = "barcode";
const SCAN_BUTTON_ID: &str = "scan_barcode_button";
const SCAN_BUTTON_ID: &str = "scan-barcode-button";
const SEARCH_FIELD_ID: &str = "myInput";
const SEARCH_FIELD_OPTIONS_ID: &str = "dropdownOptions";
const RESULT_ID_ID: &str = "id";
const RESULT_NAME_ID: &str = "name";
const RESULT_MANUFACTURER_ID: &str = "manufacturer";
const FORM_ID_ID: &str = "form-id";
const SUBMIT_BUTTON_ID: &str = "submit-button";
#[wasm_bindgen]
extern "C" {
@ -36,58 +39,45 @@ pub fn enable_panic_debug() {
utils::set_panic_hook();
}
fn get_element_by_id<T: wasm_bindgen::JsCast>(id: &str) -> Option<T> {
window()
.and_then(|x| x.document())
.and_then(|x| x.get_element_by_id(id))
.and_then(|x| x.dyn_into::<T>().ok())
}
#[wasm_bindgen]
pub fn init_camera_feed(product_options_js: JsValue) -> Result<(), String> {
let mut product_options: Vec<Nutrition> =
serde_wasm_bindgen::from_value(product_options_js).unwrap();
let test: Nutrition = //Nutrition {69, "Vitamin", "Piller", "5702071500179", 0, 0, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.};
Nutrition {
id: 69,
name: "Vitamin".to_string(),
manufacturer: "Piller".to_string(),
barcode: "5702071500179".to_string(),
amount: 0,
divisor: 0,
kJ: 0.,
kcal: 0.,
saturated_fat: 0.,
carbohydrate: 0.,
sugar: 0.,
fibres: 0.,
protein: 0.,
salt: 0.,
vitamin_b2: 0.,
vitamin_b12: 0.,
calcium: 0.,
phosphor: 0.,
let test: Nutrition = Nutrition {
id: 69,
name: "Vitamin".to_string(),
manufacturer: "Piller".to_string(),
barcode: "5702071500179".to_string(),
amount: 0,
divisor: 0,
kJ: 0.,
kcal: 0.,
saturated_fat: 0.,
carbohydrate: 0.,
sugar: 0.,
fibres: 0.,
protein: 0.,
salt: 0.,
vitamin_b2: 0.,
vitamin_b12: 0.,
calcium: 0.,
phosphor: 0.,
};
product_options.push(test);
let window = window().unwrap();
let document = window.document().unwrap();
let video: HtmlVideoElement = document
.get_element_by_id(VIDEO_ID)
.unwrap()
.dyn_into()
.unwrap();
let video2 = video.clone();
let video3 = video.clone();
let canvas: HtmlCanvasElement = document
.get_element_by_id(CANVAS_ID)
.unwrap()
.dyn_into()
.unwrap();
let button: HtmlButtonElement = document
.get_element_by_id(SCAN_BUTTON_ID)
.unwrap()
.dyn_into()
.unwrap();
let search: HtmlInputElement = document
.get_element_by_id(SEARCH_FIELD_ID)
.unwrap()
.dyn_into()
.unwrap();
let navigator = window.navigator();
let video: HtmlVideoElement = get_element_by_id(VIDEO_ID).unwrap();
let canvas: HtmlCanvasElement = get_element_by_id(CANVAS_ID).unwrap();
let button: HtmlButtonElement = get_element_by_id(SCAN_BUTTON_ID).unwrap();
let search: HtmlInputElement = get_element_by_id(SEARCH_FIELD_ID).unwrap();
let navigator = window().unwrap().navigator();
let media_devices = navigator.media_devices().unwrap();
let media_stream_constraints = MediaStreamConstraints::new();
let video_constraint = js_sys::Object::new();
@ -102,6 +92,7 @@ pub fn init_camera_feed(product_options_js: JsValue) -> Result<(), String> {
.get_user_media_with_constraints(&media_stream_constraints)
.unwrap();
let succ: Closure<dyn FnMut(JsValue)> = Closure::new(move |stream: JsValue| {
let video: HtmlVideoElement = get_element_by_id(VIDEO_ID).unwrap();
video.set_src_object(Some(&MediaStream::unchecked_from_js(stream)));
let _ = video.play();
});
@ -113,17 +104,19 @@ pub fn init_camera_feed(product_options_js: JsValue) -> Result<(), String> {
fail.forget(); // Memory leak
let set_width_and_height: Closure<dyn FnMut()> = Closure::new(move || {
let width: u32 = 300;
let height: u32 =
((width as f32 / video3.video_width() as f32) * video3.video_height() as f32) as u32;
let video: HtmlVideoElement = get_element_by_id(VIDEO_ID).unwrap();
video3.set_width(width);
video3.set_height(height);
let width: u32 = 1920;
let height: u32 =
((width as f32 / video.video_width() as f32) * video.video_height() as f32) as u32;
video.set_width(width);
video.set_height(height);
canvas.set_width(CANVAS_WIDTH);
canvas.set_height(CANVAS_HEIGHT);
});
let _ = video2
let _ = video
.add_event_listener_with_callback("canplay", set_width_and_height.as_ref().unchecked_ref());
set_width_and_height.forget(); // Memory leak
//
@ -138,10 +131,11 @@ pub fn init_camera_feed(product_options_js: JsValue) -> Result<(), String> {
scan_barcode_wrapper.forget(); // Memory leak
let show_search_options_wrapper: Closure<dyn FnMut()> = Closure::new(|| {
match show_search_options() {
Ok(()) => {}
Err(e) => error(format!("Failed to show search options: {:?}", e).as_str()),
};
show_search_options();
// match show_search_options() {
// Ok(()) => {}
// Err(e) => error(format!("Failed to show search options: {:?}", e).as_str()),
// };
});
let _ = search.add_event_listener_with_callback(
@ -152,10 +146,11 @@ pub fn init_camera_feed(product_options_js: JsValue) -> Result<(), String> {
//
let hide_search_options_wrapper: Closure<dyn FnMut(JsValue)> =
Closure::new(|event: JsValue| {
match hide_search_options(event) {
Ok(()) => {}
Err(e) => error(format!("Failed to hide search options: {:?}", e).as_str()),
};
hide_search_options(event);
// match hide_search_options(event) {
// Ok(()) => {}
// Err(e) => error(format!("Failed to hide search options: {:?}", e).as_str()),
// };
});
let _ = search.add_event_listener_with_callback(
@ -198,18 +193,10 @@ fn decode_barcode(data: Vec<u8>, width: u32, height: u32) -> Result<String, rxin
}
fn scan_barcode(product_options: Vec<Nutrition>) -> Result<(), String> {
let window = window().unwrap();
let document = window.document().unwrap();
let video: HtmlVideoElement = document
.get_element_by_id(VIDEO_ID)
.unwrap()
.dyn_into()
.unwrap();
let canvas: HtmlCanvasElement = document
.get_element_by_id(CANVAS_ID)
.unwrap()
.dyn_into()
.unwrap();
let video: HtmlVideoElement = get_element_by_id(VIDEO_ID).unwrap();
let video_container: HtmlElement = get_element_by_id(VIDEO_CONTAINER_ID).unwrap();
video_container.class_list().add_1("show").unwrap();
let canvas: HtmlCanvasElement = get_element_by_id(CANVAS_ID).unwrap();
let context: CanvasRenderingContext2d = match canvas.get_context("2d").unwrap() {
Some(c) => c.dyn_into().unwrap(),
None => return Err("Could not get canvas context".to_string()),
@ -238,6 +225,7 @@ fn scan_barcode(product_options: Vec<Nutrition>) -> Result<(), String> {
break;
}
video_container.class_list().remove_1("show").unwrap();
Ok(())
}
@ -274,33 +262,24 @@ pub async fn get_product_options() -> Result<JsValue, JsValue> {
}
fn set_product(product: &Nutrition) {
let window = window().unwrap();
let document = window.document().unwrap();
let id: HtmlElement = document
.get_element_by_id(RESULT_ID_ID)
.unwrap()
.dyn_into()
.unwrap();
let barcode: HtmlElement = document
.get_element_by_id(BARCODE_ID)
.unwrap()
.dyn_into()
.unwrap();
let name: HtmlElement = document
.get_element_by_id(RESULT_NAME_ID)
.unwrap()
.dyn_into()
.unwrap();
let manufacturer: HtmlElement = document
.get_element_by_id(RESULT_MANUFACTURER_ID)
.unwrap()
.dyn_into()
.unwrap();
let id: HtmlElement = get_element_by_id(RESULT_ID_ID).unwrap();
let form_id: HtmlElement = get_element_by_id(FORM_ID_ID).unwrap();
let barcode: HtmlElement = get_element_by_id(BARCODE_ID).unwrap();
let name: HtmlElement = get_element_by_id(RESULT_NAME_ID).unwrap();
let manufacturer: HtmlElement = get_element_by_id(RESULT_MANUFACTURER_ID).unwrap();
id.set_inner_html(&product.id().to_string());
form_id.set_inner_html(&product.id().to_string());
barcode.set_inner_html(&product.barcode());
name.set_inner_html(&product.name());
manufacturer.set_inner_html(&product.manufacturer());
log("foo!");
let submit_button: HtmlElement = get_element_by_id(SUBMIT_BUTTON_ID).unwrap();
submit_button
.attributes()
.remove_named_item("disabled")
.ok();
}
#[wasm_bindgen]
@ -360,15 +339,13 @@ fn get_search_options() -> Vec<HtmlElement> {
.unwrap_or_default()
}
fn show_search_options() -> Result<(), JsValue> {
fn show_search_options() {
get_search_options()
.into_iter()
.for_each(|elem| elem.class_list().add_1("show").unwrap());
Ok(())
}
fn hide_search_options(event_js: JsValue) -> Result<(), JsValue> {
fn hide_search_options(event_js: JsValue) {
get_search_options()
.into_iter()
.for_each(|elem| elem.class_list().remove_1("show").unwrap());
@ -394,19 +371,11 @@ fn hide_search_options(event_js: JsValue) -> Result<(), JsValue> {
}
}
}
Ok(())
}
fn filter_search_options() {
let search_options = get_search_options();
let search_string: String = window()
.unwrap()
.document()
.unwrap()
.get_element_by_id(SEARCH_FIELD_ID)
.unwrap()
.dyn_into::<HtmlInputElement>()
let search_string: String = get_element_by_id::<HtmlInputElement>(SEARCH_FIELD_ID)
.unwrap()
.value();
@ -437,13 +406,7 @@ fn filter_search_options() {
.filter(|x| shown_children.iter().all(|y| x != y))
.collect();
let window = window().unwrap();
let document = window.document().unwrap();
let search_options_field: HtmlElement = document
.get_element_by_id(SEARCH_FIELD_OPTIONS_ID)
.unwrap()
.dyn_into()
.unwrap();
let search_options_field: HtmlElement = get_element_by_id(SEARCH_FIELD_OPTIONS_ID).unwrap();
let children_arr: js_sys::Array = shown_children
.iter()

View File

@ -1,22 +1,46 @@
/* Dropdown Button */
.dropbtn {
background-color: #04AA6D;
color: white;
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
.maximize {
width: 100%;
height: 100%;
}
/* Dropdown button on hover & focus */
.dropbtn:hover, .dropbtn:focus {
background-color: #3e8e41;
.grid {
display: grid;
row-gap: 10px;
column-gap: 1%;
/* grid-template-columns: repeat( auto-fit, minmax(7.25%, 1fr) ); */
grid-template-columns: repeat(12, 1fr);
}
.subgrid {
display: grid;
grid-template-columns: subgrid;
}
.col-2 {
grid-column: span 2;
}
.col-3 {
grid-column: span 3;
}
.col-6 {
grid-column: span 6;
}
.col-12 {
grid-column: span 12;
}
#video_container {
width: 100%;
display: none;
}
/* The search field */
#myInput {
box-sizing: border-box;
background-image: url('searchicon.png');
background-image: url('/assets/searchicon.png');
background-position: 14px 12px;
background-repeat: no-repeat;
font-size: 16px;
@ -32,6 +56,7 @@
.dropdown {
position: relative;
display: inline-block;
width: 100%;
}
/* Dropdown Content (Hidden by Default) */
@ -69,3 +94,5 @@
/* Show the dropdown menu (use JS to add this class to the .dropdown-content container when the user clicks on the dropdown button) */
.show {display:block !important;}
/* vim: tabstop=2 softtabstop=2

View File

@ -75,6 +75,7 @@ async fn main() {
.nest_service("/pkg", get_service(ServeDir::new("../browser/pkg")))
.nest_service("/css", get_service(ServeDir::new("../css")))
.nest_service("/js", get_service(ServeDir::new("../javascript")))
.nest_service("/assets", get_service(ServeDir::new("../assets")))
.with_state(shared_state)
.fallback(not_found);
@ -206,6 +207,7 @@ fn construct_html(
<!DOCTYPE html>
<html lang=\"en\">
<head>
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">
{}
{}
</head>

View File

@ -65,10 +65,11 @@ fn calculate_calories_per_day(
}
});
let today_chrono = DateTime::<Utc>::from(SystemTime::now()).date_naive();
let mindate_chrono = time_date_to_chrono_naive_date(mindate);
let days_since_mindate = (today_chrono - mindate_chrono).num_days() + 1;
calorie_days.resize(days_since_mindate as usize, 0.);
// Cut plot at today
// let today_chrono = DateTime::<Utc>::from(SystemTime::now()).date_naive();
// let mindate_chrono = time_date_to_chrono_naive_date(mindate);
// let days_since_mindate = (today_chrono - mindate_chrono).num_days() + 1;
// calorie_days.resize(days_since_mindate as usize, 0.);
println!("{:?}", calorie_purchases);
println!("{:?}", mystery_meals);
@ -88,6 +89,7 @@ pub fn plot_calories_per_day(
let mindate_chrono = time_date_to_chrono_naive_date(mindate);
let maxdate_chrono = time_date_to_chrono_naive_date(maxdate);
let today_chrono = DateTime::<Utc>::from(SystemTime::now()).date_naive();
let max_calories = calorie_days
.clone()
@ -109,9 +111,19 @@ pub fn plot_calories_per_day(
.configure_mesh()
.y_desc("kcal")
.y_max_light_lines(4)
.x_max_light_lines(6)
.draw()
.unwrap();
chart
.draw_series(LineSeries::new(
vec![(today_chrono, 0.), (today_chrono, max_calories + 200.)],
BLACK.stroke_width(2),
))
.unwrap()
.label("today")
.legend(|(x, y)| PathElement::new(vec![(x, y), (x + 20, y)], BLACK));
chart
.draw_series(LineSeries::new(
calorie_days.iter().enumerate().map(|(i, cal)| {
@ -129,13 +141,13 @@ pub fn plot_calories_per_day(
.legend(|(x, y)| PathElement::new(vec![(x, y), (x + 20, y)], RED));
// Show labels
// chart
// .configure_series_labels()
// .background_style(WHITE.mix(0.8))
// .border_style(BLACK)
// .position(SeriesLabelPosition::UpperRight)
// .draw()
// .unwrap();
chart
.configure_series_labels()
.background_style(WHITE.mix(0.8))
.border_style(BLACK)
.position(SeriesLabelPosition::LowerRight)
.draw()
.unwrap();
root.present().unwrap();
});

View File

@ -1,33 +1,39 @@
<div>
<video id="video">Camera not available.</video>
<canvas id="canvas" hidden> </canvas>
</div>
<div class="dropdown">
<div id="myDropdown" class="dropdown-content">
<input type="text" placeholder="Search.." id="myInput">
<div id="dropdownOptions" class="dropdown-options"></div>
<div class="grid">
<div id="video-container" class="col-12">
<video id="video">Camera not available.</video>
<canvas id="canvas" hidden> </canvas>
</div>
<div class="dropdown col-12">
<div id="myDropdown" class="dropdown-content">
<input type="text" placeholder="Search.." id="myInput">
<div id="dropdownOptions" class="dropdown-options"></div>
</div>
</div>
<div class="col-12">
<h3>Valgt vare</h3>
<table>
<tr>
<td style="text-align: right"><b>ID:</b></td>
<td id="id"></td>
</tr>
<tr>
<td style="text-align: right"><b>Barcode:</b></td>
<td id="barcode"></td>
</tr>
<tr>
<td style="text-align: right; vertical-align: top"><b>Name:</b></td>
<td id="name" style="vertical-align: top"></td>
</tr>
<tr>
<td style="text-align: right"><b>Manufacturer:</b></td> <td id="manufacturer"></td>
</tr>
</table>
</div>
<div class="subgrid col-12" style="height: 100px">
<form id="submit-form" class="col-6" onsubmit="return confirm('Do you really want to submit the form?');">
<input id="form-id" hidden>
<input id="submit-button" class="maximize" type="submit" value="Submit" disabled>
</form>
<button id="scan-barcode-button" class="col-6">Scan barcode</button>
</div>
</div>
<div>
<button id="scan_barcode_button">Scan barcode</button>
</div>
<div>
<h3>Valgt vare</h3>
<table>
<tr>
<td><b>ID:</b></td>
<td id="id"></td>
</tr>
<tr>
<td><b>Barcode:</b></td>
<td id="barcode"></td>
</tr>
<tr>
<td><b>Name:</b></td>
<td id="name"></td>
</tr>
<tr>
<td><b>Manufacturer:</b></td> <td id="manufacturer"></td>
</tr>
</table>
</div>