Skip to content

Commit

Permalink
upload
Browse files Browse the repository at this point in the history
  • Loading branch information
kroune committed Aug 24, 2024
1 parent 0375f70 commit 563d3e4
Show file tree
Hide file tree
Showing 8 changed files with 354 additions and 4 deletions.
7 changes: 7 additions & 0 deletions src-theme/src/integration/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface GroupedModules {

export type ModuleSetting =
BlocksSetting
| ItemsSetting
| KeySetting
| BooleanSetting
| FloatSetting
Expand All @@ -35,6 +36,12 @@ export interface BlocksSetting {
value: string[];
}

export interface ItemsSetting {
valueType: string;
name: string;
value: string;
}

export interface TextSetting {
valueType: string;
name: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import ColorSetting from "../ColorSetting.svelte";
import TextSetting from "../TextSetting.svelte";
import KeySetting from "../KeySetting.svelte";
import ItemsSetting from "../items/ItemSetting.svelte";
import BlocksSetting from "../blocks/BlocksSetting.svelte";
import {slide} from "svelte/transition";
import {onMount} from "svelte";
Expand Down Expand Up @@ -56,6 +57,8 @@
<TextSetting bind:setting={setting} on:change/>
{:else if setting.valueType === "KEY"}
<KeySetting bind:setting={setting} on:change/>
{:else if setting.valueType === "ITEMS"}
<ItemsSetting bind:setting={setting} on:change/>
{:else if setting.valueType === "BLOCKS"}
<BlocksSetting bind:setting={setting} on:change/>
{:else if setting.valueType === "TEXT_ARRAY"}
Expand All @@ -64,4 +67,4 @@
<div style="color: white">Unsupported setting {setting.valueType}</div>
{/if}
</div>
{/if}
{/if}
52 changes: 52 additions & 0 deletions src-theme/src/routes/clickgui/setting/items/Item.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<script lang="ts">
import {REST_BASE} from "../../../../integration/host";
import {createEventDispatcher} from "svelte";
const dispatch = createEventDispatcher<{
toggle: { identifier: string, enabled: boolean }
}>();
export let identifier: string;
export let name: string;
export let enabled: boolean;
</script>

<!-- svelte-ignore a11y-no-static-element-interactions -->
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div class="item" on:click={() => dispatch("toggle", {enabled: !enabled, identifier})}>
<img class="icon" src="{REST_BASE}/api/v1/client/resource/itemTexture?id={identifier}" alt={identifier}/>
<div class="name">{name}</div>
<div class="tick">
{#if enabled}
<img src="img/clickgui/icon-tick-checked.svg" alt="enabled">
{:else}
<img src="img/clickgui/icon-tick.svg" alt="disabled">
{/if}
</div>
</div>

<style lang="scss">
@import "../../../../colors.scss";
.item {
display: grid;
grid-template-columns: max-content 1fr max-content;
align-items: center;
column-gap: 5px;
cursor: pointer;
margin: 2px 5px 2px 0;
}
.icon {
height: 25px;
width: 25px;
}
.name {
font-size: 12px;
color: $clickgui-text-color;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
</style>
93 changes: 93 additions & 0 deletions src-theme/src/routes/clickgui/setting/items/ItemSetting.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<script lang="ts">
import {createEventDispatcher, onMount} from "svelte";
import type {ItemsSetting, ModuleSetting} from "../../../../integration/types";
import {getRegistries} from "../../../../integration/rest";
import Item from "./Item.svelte";
import VirtualList from "./VirtualList.svelte";
import {convertToSpacedString, spaceSeperatedNames} from "../../../../theme/theme_config";
export let setting: ModuleSetting;
const cSetting = setting as ItemsSetting;
interface Item {
name: string;
identifier: string;
}
const dispatch = createEventDispatcher();
let items: Item[] = [];
let renderedItems: Item[] = items;
let searchQuery = "";
$: {
let filteredItems = items;
if (searchQuery) {
filteredItems = filteredItems.filter(b => b.name.toLowerCase().includes(searchQuery.toLowerCase()));
}
renderedItems = filteredItems;
}
onMount(async () => {
let i = (await getRegistries()).items;
if (i !== undefined) {
items = i.sort((a, b) => a.identifier.localeCompare(b.identifier));
}
});
function handleItemToggle(e: CustomEvent<{ identifier: string, enabled: boolean }>) {
console.log(e);
if (e.detail.enabled) {
cSetting.value = [...cSetting.value, e.detail.identifier];
} else {
cSetting.value = cSetting.value.filter(b => b !== e.detail.identifier);
}
setting = { ...cSetting };
dispatch("change");
}
</script>

<div class="setting">
<div class="name">{$spaceSeperatedNames ? convertToSpacedString(cSetting.name) : cSetting.name}</div>
<input type="text" placeholder="Search" class="search-input" bind:value={searchQuery} spellcheck="false">
<div class="results">
<VirtualList items={renderedItems} let:item>
<Item identifier={item.identifier} name={item.name} enabled={cSetting.value.includes(item.identifier)} on:toggle={handleItemToggle}/>
</VirtualList>
</div>
</div>

<style lang="scss">
@import "../../../../colors.scss";
.setting {
padding: 7px 0;
}
.results {
height: 200px;
overflow-y: auto;
overflow-x: hidden;
}
.name {
color: $clickgui-text-color;
font-size: 12px;
font-weight: 500;
margin-bottom: 5px;
}
.search-input {
width: 100%;
border: none;
border-bottom: solid 1px $accent-color;
font-family: "Inter", sans-serif;
font-size: 12px;
padding: 5px;
color: $clickgui-text-color;
margin-bottom: 5px;
background-color: rgba($clickgui-base-color, .36);
}
</style>
137 changes: 137 additions & 0 deletions src-theme/src/routes/clickgui/setting/items/VirtualList.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
<!-- Adapted from https://github.com/sveltejs/svelte-virtual-list -->
<script lang="js">
import {onMount, tick} from 'svelte';
// props
export let items;
export let height = '100%';
export let itemHeight = undefined;
// read-only, but visible to consumers via bind:start
export let start = 0;
export let end = 0;
// local state
let height_map = [];
let rows;
let viewport;
let contents;
let viewport_height = 0;
let visible;
let mounted;
let top = 0;
let bottom = 0;
let average_height;
$: visible = items.slice(start, end).map((data, i) => {
return { index: i + start, data };
});
// whenever `items` changes, invalidate the current heightmap
$: if (mounted) refresh(items, viewport_height, itemHeight);
async function refresh(items, viewport_height, itemHeight) {
const { scrollTop } = viewport;
await tick(); // wait until the DOM is up to date
let content_height = top - scrollTop;
let i = start;
while (content_height < viewport_height && i < items.length) {
let row = rows[i - start];
if (!row) {
end = i + 1;
await tick(); // render the newly visible row
row = rows[i - start];
}
const row_height = height_map[i] = itemHeight || row.offsetHeight;
content_height += row_height;
i += 1;
}
end = i;
const remaining = items.length - end;
average_height = (top + content_height) / end;
bottom = remaining * average_height;
height_map.length = items.length;
setTimeout(() => {
viewport.scrollTop = 0;
}, 100);
}
async function handle_scroll() {
const { scrollTop } = viewport;
const old_start = start;
for (let v = 0; v < rows.length; v += 1) {
height_map[start + v] = itemHeight || rows[v].offsetHeight;
}
let i = 0;
let y = 0;
while (i < items.length) {
const row_height = height_map[i] || average_height;
if (y + row_height > scrollTop) {
start = i;
top = y;
break;
}
y += row_height;
i += 1;
}
while (i < items.length) {
y += height_map[i] || average_height;
i += 1;
if (y > scrollTop + viewport_height) break;
}
end = i;
const remaining = items.length - end;
average_height = y / end;
while (i < items.length) height_map[i++] = average_height;
bottom = remaining * average_height;
// prevent jumping if we scrolled up into unknown territory
if (start < old_start) {
await tick();
let expected_height = 0;
let actual_height = 0;
for (let i = start; i < old_start; i +=1) {
if (rows[i - start]) {
expected_height += height_map[i];
actual_height += itemHeight || rows[i - start].offsetHeight;
}
}
const d = actual_height - expected_height;
viewport.scrollTo(0, scrollTop + d);
}
// TODO if we overestimated the space these
// rows would occupy we may need to add some
// more. maybe we can just call handle_scroll again?
}
// trigger initial refresh
onMount(() => {
rows = contents.getElementsByTagName('svelte-virtual-list-row');
mounted = true;
});
</script>

<style>
svelte-virtual-list-viewport {
position: relative;
overflow-y: auto;
-webkit-overflow-scrolling:touch;
display: block;
}
svelte-virtual-list-contents, svelte-virtual-list-row {
display: block;
}
svelte-virtual-list-row {
overflow: hidden;
}
</style>

<svelte-virtual-list-viewport
bind:this={viewport}
bind:offsetHeight={viewport_height}
on:scroll={handle_scroll}
style="height: {height};"
>
<svelte-virtual-list-contents
bind:this={contents}
style="padding-top: {top}px; padding-bottom: {bottom}px;"
>
{#each visible as row (row.index)}
<svelte-virtual-list-row>
<slot item={row.data}>Missing template</slot>
</svelte-virtual-list-row>
{/each}
</svelte-virtual-list-contents>
</svelte-virtual-list-viewport>
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
package net.ccbluex.liquidbounce.features.module.modules.player.invcleaner

import net.ccbluex.liquidbounce.features.module.modules.player.invcleaner.items.ItemFacet
import net.ccbluex.liquidbounce.utils.client.logger
import net.ccbluex.liquidbounce.utils.item.isNothing
import net.minecraft.item.Item

class CleanupPlanGenerator(
private val template: CleanupPlanPlacementTemplate,
Expand Down Expand Up @@ -58,6 +60,18 @@ class CleanupPlanGenerator(
processItemCategory(category, availableItems)
}

availableItems.forEach { slot ->
val limit = template.itemLimitPerItem[slot.itemStack.item] ?: Int.MAX_VALUE
var itemCount = packer.usefulItems.count { it.itemStack.item == slot.itemStack.item }
packer.usefulItems.removeIf {
if (itemCount > limit) {
logger.info("removed item from useful items list")
itemCount--
return@removeIf true
}
false
}
}
// We aren't allowed to touch those, so we just consider them as useful.
packer.usefulItems.addAll(this.template.forbiddenSlots)

Expand All @@ -74,7 +88,7 @@ class CleanupPlanGenerator(
) {
val maxItemCount =
if (category.type.oneIsSufficient) {
if (this.packer.alreadyProviededFunctions.contains(category.type.providedFunction)) 0 else 1
if (this.packer.alreadyProvidedFunctions.contains(category.type.providedFunction)) 0 else 1
} else {
template.itemLimitPerCategory[category] ?: Int.MAX_VALUE
}
Expand Down Expand Up @@ -132,6 +146,7 @@ class CleanupPlanPlacementTemplate(
* If an item is not in this map, there is no limit.
*/
val itemLimitPerCategory: Map<ItemCategory, Int>,
val itemLimitPerItem: Map<Item, Int>,
/**
* If false, slots which also contains items of that category, those items are not replaced with other items.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class ItemPacker {
*/
val usefulItems = HashSet<ItemSlot>()

val alreadyProviededFunctions = HashSet<ItemFunction>()
val alreadyProvidedFunctions = HashSet<ItemFunction>()

/**
* Takes items from the [itemsToFillIn] list until it collected [maxItemCount] items is and [requiredStackCount]
Expand Down Expand Up @@ -61,7 +61,7 @@ class ItemPacker {

usefulItems.add(filledInItemSlot)

alreadyProviededFunctions.addAll(filledInItem.providedItemFunctions)
alreadyProvidedFunctions.addAll(filledInItem.providedItemFunctions)

currentItemCount += filledInItem.itemStack.count
currentStackCount++
Expand Down
Loading

0 comments on commit 563d3e4

Please sign in to comment.