diff --git a/ic10emu/src/lib.rs b/ic10emu/src/lib.rs index ed369a3..6ea4495 100644 --- a/ic10emu/src/lib.rs +++ b/ic10emu/src/lib.rs @@ -14,6 +14,7 @@ use grammar::{BatchMode, LogicType, ReagentMode, SlotLogicType}; use interpreter::{ICError, LineError}; use itertools::Itertools; use serde::{Deserialize, Serialize}; +use strum_macros::{EnumIter, EnumString, AsRefStr}; use thiserror::Error; use crate::interpreter::ICState; @@ -348,8 +349,22 @@ impl Connection { } } -#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] - +#[derive( + Debug, + Default, + Clone, + Copy, + PartialEq, + Eq, + Hash, + strum_macros::Display, + EnumString, + EnumIter, + AsRefStr, + Serialize, + Deserialize, +)] +#[strum(serialize_all = "PascalCase")] pub enum SlotType { Helmet = 1, Suit = 2, @@ -376,7 +391,7 @@ pub enum SlotType { Magazine, Circuit = 24, Bottle, - ProgramableChip, + ProgrammableChip, Glasses, CreditCard, DirtCanister, @@ -390,7 +405,6 @@ pub enum SlotType { Flare, Blocked, #[default] - #[serde(other)] None = 0, } @@ -423,8 +437,7 @@ impl Network { } pub fn contains_all(&self, ids: &[u32]) -> bool { - ids.iter() - .all(|id| self.contains(id)) + ids.iter().all(|id| self.contains(id)) } pub fn contains_data(&self, id: &u32) -> bool { @@ -588,7 +601,7 @@ impl Device { ), ]); device.slots.push(Slot::with_occupant( - SlotType::ProgramableChip, + SlotType::ProgrammableChip, // -744098481 = ItemIntegratedCircuit10 SlotOccupant::new(ic, -744098481), )); @@ -710,7 +723,7 @@ impl Device { .slots .get(index as usize) .ok_or(ICError::SlotIndexOutOfRange(index))?; - if slot.typ == SlotType::ProgramableChip + if slot.typ == SlotType::ProgrammableChip && slot.occupant.is_some() && self.ic.is_some() && typ == SlotLogicType::LineNumber @@ -743,7 +756,7 @@ impl Device { .get(index as usize) .ok_or(ICError::SlotIndexOutOfRange(index))?; let mut fields = slot.get_fields(); - if slot.typ == SlotType::ProgramableChip && slot.occupant.is_some() && self.ic.is_some() { + if slot.typ == SlotType::ProgrammableChip && slot.occupant.is_some() && self.ic.is_some() { // try borrow to get ip, we should only fail if the ic is in us aka is is *our* ic if let Ok(ic) = vm .ics @@ -784,7 +797,7 @@ impl Device { .slots .get_mut(index as usize) .ok_or(ICError::SlotIndexOutOfRange(index))?; - if slot.typ == SlotType::ProgramableChip + if slot.typ == SlotType::ProgrammableChip && slot.occupant.is_some() && self.ic.is_some() && typ == SlotLogicType::LineNumber @@ -1114,7 +1127,7 @@ impl VM { let ic = slots .iter() .find_map(|slot| { - if slot.typ == SlotType::ProgramableChip && slot.occupant.is_some() { + if slot.typ == SlotType::ProgrammableChip && slot.occupant.is_some() { Some(slot.occupant.clone()).flatten() } else { None diff --git a/ic10emu_wasm/src/lib.rs b/ic10emu_wasm/src/lib.rs index f554509..60a6192 100644 --- a/ic10emu_wasm/src/lib.rs +++ b/ic10emu_wasm/src/lib.rs @@ -2,7 +2,10 @@ mod utils; mod types; -use ic10emu::{grammar::{LogicType, SlotLogicType}, DeviceTemplate}; +use ic10emu::{ + grammar::{LogicType, SlotLogicType}, + DeviceTemplate, +}; use serde::{Deserialize, Serialize}; use types::{Registers, Stack}; @@ -61,12 +64,20 @@ impl DeviceRef { #[wasm_bindgen(getter, js_name = "prefabName")] pub fn prefab_name(&self) -> Option { - self.device.borrow().prefab.as_ref().map(|prefab| prefab.name.clone()) + self.device + .borrow() + .prefab + .as_ref() + .map(|prefab| prefab.name.clone()) } #[wasm_bindgen(getter, js_name = "prefabHash")] pub fn prefab_hash(&self) -> Option { - self.device.borrow().prefab.as_ref().map(|prefab| prefab.hash) + self.device + .borrow() + .prefab + .as_ref() + .map(|prefab| prefab.hash) } #[wasm_bindgen(getter, skip_typescript)] @@ -354,6 +365,10 @@ impl VM { #[wasm_bindgen(js_name = "addDeviceFromTemplate", skip_typescript)] pub fn add_device_from_template(&self, template: JsValue) -> Result { let template: DeviceTemplate = serde_wasm_bindgen::from_value(template)?; + web_sys::console::log_2( + &"(wasm) adding device".into(), + &serde_wasm_bindgen::to_value(&template).unwrap(), + ); Ok(self.vm.borrow_mut().add_device_from_template(template)?) } diff --git a/www/assets_finding.ipynb b/www/assets_finding.ipynb index 9f34731..4fa48fd 100644 --- a/www/assets_finding.ipynb +++ b/www/assets_finding.ipynb @@ -15,7 +15,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -38,7 +38,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -58,7 +58,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -80,7 +80,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ @@ -178,8 +178,7 @@ " candidates.append((name, entry[\"name\"].removeprefix(\"Item\"), entry[\"name\"]))\n", " if entry[\"name\"].removeprefix(\"Structure\") in name:\n", " candidates.append((name, entry[\"name\"].removeprefix(\"Structure\"), entry[\"name\"]))\n", - " image_candidates[entry[\"name\"]] = filter_candidates(candidates)\n", - "\n" + " image_candidates[entry[\"name\"]] = filter_candidates(candidates)" ] }, { @@ -191,7 +190,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 17, "metadata": {}, "outputs": [], "source": [ @@ -212,30 +211,30 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "ItemBiomass []\n", - "StructureBlocker []\n", "CartridgePlantAnalyser []\n", - "StructureElevatorLevelIndustrial []\n", - "ItemPlantEndothermic_Creative []\n", "Flag_ODA_10m []\n", "Flag_ODA_4m []\n", "Flag_ODA_6m []\n", "Flag_ODA_8m []\n", + "ItemBiomass []\n", "ItemHorticultureBelt []\n", "ItemKitLiquidRegulator []\n", "ItemKitPortablesConnector []\n", + "ItemMushroom ['ItemMushroom-resources.assets-3022.png', 'ItemMushroom-resources.assets-9304.png']\n", + "ItemPlantEndothermic_Creative []\n", + "ItemPlantThermogenic_Creative []\n", "Landingpad_GasConnectorInwardPiece []\n", "Landingpad_LiquidConnectorInwardPiece []\n", - "ItemMushroom ['ItemMushroom-resources.assets-3022.png', 'ItemMushroom-resources.assets-9304.png']\n", - "StructurePlinth []\n", - "ItemPlantThermogenic_Creative []\n" + "StructureBlocker []\n", + "StructureElevatorLevelIndustrial []\n", + "StructurePlinth []\n" ] } ], @@ -254,14 +253,95 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "1223 of 1223 | 100.00% \n", + "missing Egg\n", + "missing Appliance\n", + "missing Ingot\n", + "missing Torpedo\n", + "missing Magazine\n", + "missing SensorProcessingUnit\n", + "missing LiquidCanister\n", + "missing LiquidBottle\n", + "missing Wreckage\n", + "missing SoundCartridge\n", + "missing DrillHead\n", + "missing ScanningHead\n", + "missing Flare\n", + "missing Blocked\n" + ] + } + ], + "source": [ + "slot_types = [\n", + " \"Helmet\",\n", + " \"Suit\",\n", + " \"Back\",\n", + " \"GasFilter\",\n", + " \"GasCanister\",\n", + " \"MotherBoard\",\n", + " \"Circuitboard\",\n", + " \"DataDisk\",\n", + " \"Organ\",\n", + " \"Ore\",\n", + " \"Plant\",\n", + " \"Uniform\",\n", + " \"Entity\",\n", + " \"Battery\",\n", + " \"Egg\",\n", + " \"Belt\",\n", + " \"Tool\",\n", + " \"Appliance\",\n", + " \"Ingot\",\n", + " \"Torpedo\",\n", + " \"Cartridge\",\n", + " \"AccessCard\",\n", + " \"Magazine\",\n", + " \"Circuit\",\n", + " \"Bottle\",\n", + " \"ProgrammableChip\",\n", + " \"Glasses\",\n", + " \"CreditCard\",\n", + " \"DirtCanister\",\n", + " \"SensorProcessingUnit\",\n", + " \"LiquidCanister\",\n", + " \"LiquidBottle\",\n", + " \"Wreckage\",\n", + " \"SoundCartridge\",\n", + " \"DrillHead\",\n", + " \"ScanningHead\",\n", + " \"Flare\",\n", + " \"Blocked\",\n", + "]\n", + "sloticons = []\n", + "for typ in slot_types:\n", + " try_name = f\"sloticon_{typ.lower()}\"\n", + " found = False\n", + " for name in names:\n", + " if name.startswith(try_name):\n", + " sloticons.append([f\"SlotIcon_{typ}\", name])\n", + " found = True\n", + " if not found:\n", + " print(f\"missing {typ}\")\n", + "\n", + "to_copy.extend(sloticons)" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1266 of 1266 | 100.00% \n", "Done\n" ] } @@ -284,13 +364,6 @@ "print(\"Done\")\n", "\n" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { diff --git a/www/img/stationpedia/SlotIcon_AccessCard.png b/www/img/stationpedia/SlotIcon_AccessCard.png new file mode 100644 index 0000000..e329d01 Binary files /dev/null and b/www/img/stationpedia/SlotIcon_AccessCard.png differ diff --git a/www/img/stationpedia/SlotIcon_Back.png b/www/img/stationpedia/SlotIcon_Back.png new file mode 100644 index 0000000..20ac6df Binary files /dev/null and b/www/img/stationpedia/SlotIcon_Back.png differ diff --git a/www/img/stationpedia/SlotIcon_Battery.png b/www/img/stationpedia/SlotIcon_Battery.png new file mode 100644 index 0000000..8570de9 Binary files /dev/null and b/www/img/stationpedia/SlotIcon_Battery.png differ diff --git a/www/img/stationpedia/SlotIcon_Belt.png b/www/img/stationpedia/SlotIcon_Belt.png new file mode 100644 index 0000000..d222aa0 Binary files /dev/null and b/www/img/stationpedia/SlotIcon_Belt.png differ diff --git a/www/img/stationpedia/SlotIcon_Bottle.png b/www/img/stationpedia/SlotIcon_Bottle.png new file mode 100644 index 0000000..16f7238 Binary files /dev/null and b/www/img/stationpedia/SlotIcon_Bottle.png differ diff --git a/www/img/stationpedia/SlotIcon_Cartridge.png b/www/img/stationpedia/SlotIcon_Cartridge.png new file mode 100644 index 0000000..81fe51d Binary files /dev/null and b/www/img/stationpedia/SlotIcon_Cartridge.png differ diff --git a/www/img/stationpedia/SlotIcon_Circuit.png b/www/img/stationpedia/SlotIcon_Circuit.png new file mode 100644 index 0000000..1d98394 Binary files /dev/null and b/www/img/stationpedia/SlotIcon_Circuit.png differ diff --git a/www/img/stationpedia/SlotIcon_Circuitboard.png b/www/img/stationpedia/SlotIcon_Circuitboard.png new file mode 100644 index 0000000..1d98394 Binary files /dev/null and b/www/img/stationpedia/SlotIcon_Circuitboard.png differ diff --git a/www/img/stationpedia/SlotIcon_CreditCard.png b/www/img/stationpedia/SlotIcon_CreditCard.png new file mode 100644 index 0000000..c6cafa7 Binary files /dev/null and b/www/img/stationpedia/SlotIcon_CreditCard.png differ diff --git a/www/img/stationpedia/SlotIcon_DataDisk.png b/www/img/stationpedia/SlotIcon_DataDisk.png new file mode 100644 index 0000000..a0d2dbf Binary files /dev/null and b/www/img/stationpedia/SlotIcon_DataDisk.png differ diff --git a/www/img/stationpedia/SlotIcon_DirtCanister.png b/www/img/stationpedia/SlotIcon_DirtCanister.png new file mode 100644 index 0000000..4bc42fe Binary files /dev/null and b/www/img/stationpedia/SlotIcon_DirtCanister.png differ diff --git a/www/img/stationpedia/SlotIcon_Entity.png b/www/img/stationpedia/SlotIcon_Entity.png new file mode 100644 index 0000000..562a8f4 Binary files /dev/null and b/www/img/stationpedia/SlotIcon_Entity.png differ diff --git a/www/img/stationpedia/SlotIcon_GasCanister.png b/www/img/stationpedia/SlotIcon_GasCanister.png new file mode 100644 index 0000000..1804c7c Binary files /dev/null and b/www/img/stationpedia/SlotIcon_GasCanister.png differ diff --git a/www/img/stationpedia/SlotIcon_GasFilter.png b/www/img/stationpedia/SlotIcon_GasFilter.png new file mode 100644 index 0000000..4d8ee99 Binary files /dev/null and b/www/img/stationpedia/SlotIcon_GasFilter.png differ diff --git a/www/img/stationpedia/SlotIcon_Glasses.png b/www/img/stationpedia/SlotIcon_Glasses.png new file mode 100644 index 0000000..001d76a Binary files /dev/null and b/www/img/stationpedia/SlotIcon_Glasses.png differ diff --git a/www/img/stationpedia/SlotIcon_Helmet.png b/www/img/stationpedia/SlotIcon_Helmet.png new file mode 100644 index 0000000..02ee80a Binary files /dev/null and b/www/img/stationpedia/SlotIcon_Helmet.png differ diff --git a/www/img/stationpedia/SlotIcon_Motherboard.png b/www/img/stationpedia/SlotIcon_Motherboard.png new file mode 100644 index 0000000..bdc75fe Binary files /dev/null and b/www/img/stationpedia/SlotIcon_Motherboard.png differ diff --git a/www/img/stationpedia/SlotIcon_Ore.png b/www/img/stationpedia/SlotIcon_Ore.png new file mode 100644 index 0000000..f837faa Binary files /dev/null and b/www/img/stationpedia/SlotIcon_Ore.png differ diff --git a/www/img/stationpedia/SlotIcon_Organ.png b/www/img/stationpedia/SlotIcon_Organ.png new file mode 100644 index 0000000..71ff895 Binary files /dev/null and b/www/img/stationpedia/SlotIcon_Organ.png differ diff --git a/www/img/stationpedia/SlotIcon_Plant.png b/www/img/stationpedia/SlotIcon_Plant.png new file mode 100644 index 0000000..f31ae58 Binary files /dev/null and b/www/img/stationpedia/SlotIcon_Plant.png differ diff --git a/www/img/stationpedia/SlotIcon_ProgrammableChip.png b/www/img/stationpedia/SlotIcon_ProgrammableChip.png new file mode 100644 index 0000000..a3789a5 Binary files /dev/null and b/www/img/stationpedia/SlotIcon_ProgrammableChip.png differ diff --git a/www/img/stationpedia/SlotIcon_Suit.png b/www/img/stationpedia/SlotIcon_Suit.png new file mode 100644 index 0000000..6f8940e Binary files /dev/null and b/www/img/stationpedia/SlotIcon_Suit.png differ diff --git a/www/img/stationpedia/SlotIcon_Tool.png b/www/img/stationpedia/SlotIcon_Tool.png new file mode 100644 index 0000000..38ca0a7 Binary files /dev/null and b/www/img/stationpedia/SlotIcon_Tool.png differ diff --git a/www/img/stationpedia/SlotIcon_Uniform.png b/www/img/stationpedia/SlotIcon_Uniform.png new file mode 100644 index 0000000..ba737fd Binary files /dev/null and b/www/img/stationpedia/SlotIcon_Uniform.png differ diff --git a/www/src/ts/components/details.ts b/www/src/ts/components/details.ts index bcb1df3..e736c54 100644 --- a/www/src/ts/components/details.ts +++ b/www/src/ts/components/details.ts @@ -22,6 +22,9 @@ export class IC10Details extends SlDetails { .details__summary-icon { cursor: pointer; } + .details__content { + padding-top: 0; + } `, ]; diff --git a/www/src/ts/virtual_machine/device.ts b/www/src/ts/virtual_machine/device.ts index 57fae23..71c0ac7 100644 --- a/www/src/ts/virtual_machine/device.ts +++ b/www/src/ts/virtual_machine/device.ts @@ -10,6 +10,7 @@ import { SlotOccupantTemplate, SlotLogicType, ConnectionCableNetwork, + SlotType, } from "ic10emu_wasm"; import { html, css, HTMLTemplateResult } from "lit"; import { customElement, property, query, state } from "lit/decorators.js"; @@ -94,6 +95,13 @@ export class VMDeviceCard extends VMDeviceMixin(BaseElement) { .device-name-hash::part(input) { width: 7rem; } + .slot-header.image { + width: 1.5rem; + height: 1.5rem; + border: var(--sl-panel-border-width) solid var(--sl-panel-border-color); + border-radius: var(--sl-border-radius-medium); + background-color: var(--sl-color-neutral-0); + } sl-divider { --spacing: 0.25rem; } @@ -119,12 +127,35 @@ export class VMDeviceCard extends VMDeviceMixin(BaseElement) { padding: var(--sl-spacing-small) var(--sl-spacing-medium); } sl-tab-group::part(base) { - height: 16rem; + max-height: 20rem; overflow-y: auto; } `, ]; + private _deviceDB: DeviceDB; + + get deviceDB(): DeviceDB { + return this._deviceDB; + } + + @state() + set deviceDB(val: DeviceDB) { + this._deviceDB = val; + } + + connectedCallback(): void { + super.connectedCallback(); + window.VM!.addEventListener( + "vm-device-db-loaded", + this._handleDeviceDBLoad.bind(this), + ); + } + + _handleDeviceDBLoad(e: CustomEvent) { + this.deviceDB = e.detail; + } + onImageErr(e: Event) { this.image_err = true; console.log("Image load error", e); @@ -145,7 +176,8 @@ export class VMDeviceCard extends VMDeviceMixin(BaseElement) { }, this); return html` - +
{ - return html` ${name} @@ -183,17 +215,53 @@ export class VMDeviceCard extends VMDeviceMixin(BaseElement) { `; } + lookupSlotOccupantImg( + occupant: SlotOccupant | undefined, + typ: SlotType, + ): string { + if (typeof occupant !== "undefined") { + const hashLookup = (this.deviceDB ?? {}).names_by_hash ?? {}; + const prefabName = hashLookup[occupant.prefab_hash] ?? "UnknownHash"; + return `img/stationpedia/${prefabName}.png`; + } else { + return `img/stationpedia/SlotIcon_${typ}.png`; + } + } + + _onSlotImageErr(e: Event) { + console.log("image_err", e); + } + + static transparentImg = + "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" as const; + renderSlot(slot: Slot, slotIndex: number): HTMLTemplateResult { const _fields = this.device.getSlotFields(slotIndex); const fields = Array.from(_fields.entries()); const inputIdBase = `vmDeviceCard${this.deviceID}Slot${slotIndex}Field`; + const slotImg = this.lookupSlotOccupantImg(slot.occupant, slot.typ); return html` + ${slotIndex} : ${slot.typ} + ${ + typeof slot.occupant !== "undefined" + ? html` + + Occupant: ${slot.occupant.id} : ${slot.occupant.prefab_hash} + + + Quantity: ${slot.occupant.quantity}/ + ${slot.occupant.max_quantity} + + ` + : "" + }
${fields.map( ([name, field], _index, _fields) => html` - ${name} @@ -221,42 +289,49 @@ export class VMDeviceCard extends VMDeviceMixin(BaseElement) { renderNetworks(): HTMLTemplateResult { const vmNetworks = window.VM!.networks; return html` -
- ${this.connections.map((connection, index, _conns) => { - const conn = - typeof connection === "object" ? connection.CableNetwork : null; - return html` - - Connection:${index} - ${vmNetworks.map( - (net) => - html`Network ${net}`, - )} - ${conn?.typ} - - `; - })} -
- `; + < div class="networks" > + ${ + this.connections.map((connection, index, _conns) => { + const conn = + typeof connection === "object" ? connection.CableNetwork : null; + return html` + + Connection:${index} + ${vmNetworks.map( + (net) => + html`Network ${net}`, + )} + ${conn?.typ} + + `; + }) + } +
+ `; } renderPins(): HTMLTemplateResult { const pins = this.pins; const visibleDevices = window.VM!.visibleDevices(this.deviceID); return html` -
- ${pins?.map( - (pin, index) => - html` - d${index} - ${visibleDevices.map( - (device, _index) => - html` - Device ${device.id} : ${device.name ?? device.prefabName} - `, - )} - `, - )} + < div class="pins" > + ${ + pins?.map( + (pin, index) => + html` + + d${index} + ${visibleDevices.map( + (device, _index) => + html` + + Device ${device.id} : ${device.name ?? device.prefabName} + + `, + )} + `, + ) + }
`; } @@ -383,9 +458,9 @@ export class VMDeviceList extends BaseElement { } protected render(): HTMLTemplateResult { - const deviceCards: HTMLTemplateResult[] = this.devices.map( + const deviceCards: HTMLTemplateResult[] = this.filteredDeviceIds.map( (id, _index, _ids) => - html``, + html`< vm - device - card.deviceID=${ id } class="device-list-card" > `, ); const result = html`
@@ -393,6 +468,9 @@ export class VMDeviceList extends BaseElement { Devices: ${this.devices.length} + + " +
${deviceCards}
@@ -400,6 +478,70 @@ export class VMDeviceList extends BaseElement { return result; } + + get filteredDeviceIds() { + if (typeof this._filteredDeviceIds !== "undefined") { + return this._filteredDeviceIds; + } else { + return this.devices; + } + } + + private _filteredDeviceIds: number[] | undefined; + private _filter: string = ""; + + @query(".device-filter-input") accessor filterInput: SlInput; + get filter() { + return this._filter; + } + + @state() + set filter(val: string) { + this._filter = val; + this.performSearch(); + } + + private filterTimeout: number | undefined; + + _handleFilterInput(_e: CustomEvent) { + if (this.filterTimeout) { + clearTimeout(this.filterTimeout); + } + const that = this; + this.filterTimeout = setTimeout(() => { + that.filter = that.filterInput.value; + that.filterTimeout = undefined; + }, 200); + } + + performSearch() { + if (this._filter) { + const datapoints: [string, number][] = []; + for (const device_id of this.devices) { + const device = window.VM.devices.get(device_id); + if (device) { + if (typeof device.name !== "undefined") { + datapoints.push([device.name, device.id]); + } + if (typeof device.prefabName !== "undefined") { + datapoints.push([device.prefabName, device.id]); + } + } + } + const haystack: string[] = datapoints.map((data) => data[0]); + const uf = new uFuzzy({}); + const [_idxs, info, order] = uf.search(haystack, this._filter, 0, 1e3); + + const filtered = order?.map((infoIdx) => datapoints[info.idx[infoIdx]]); + const deviceIds: number[] = + filtered + ?.map((data) => data[1]) + ?.filter((val, index, arr) => arr.indexOf(val) === index) ?? []; + this._filteredDeviceIds = deviceIds; + } else { + this._filteredDeviceIds = undefined; + } + } } @customElement("vm-add-device-button") @@ -465,7 +607,7 @@ export class VMAddDeviceButton extends BaseElement { this.performSearch(); } - _filter: string = ""; + private _filter: string = ""; get filter() { return this._filter; @@ -482,7 +624,7 @@ export class VMAddDeviceButton extends BaseElement { private filterTimeout: number | undefined; performSearch() { - if (this.filter) { + if (this._filter) { const uf = new uFuzzy({}); const [_idxs, info, order] = uf.search( this._haystack, @@ -556,7 +698,6 @@ export class VMAddDeviceButton extends BaseElement { } _handleSearchInput(e: CustomEvent) { - console.log("search-input", e); if (this.filterTimeout) { clearTimeout(this.filterTimeout); } @@ -687,12 +828,11 @@ export class VmDeviceTemplate extends BaseElement { } connectedCallback(): void { - const root = super.connectedCallback(); + super.connectedCallback(); window.VM!.addEventListener( "vm-device-db-loaded", this._handleDeviceDBLoad.bind(this), ); - return root; } _handleDeviceDBLoad(e: CustomEvent) { @@ -784,7 +924,8 @@ export class VmDeviceTemplate extends BaseElement {
- +
${device?.name}