All files / src/views model-info-modal.ts

100% Statements 53/53
100% Branches 16/16
100% Functions 6/6
100% Lines 53/53

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 751x                             1x 11x   11x 11x 11x 11x 11x   11x 7x 7x 7x   7x 7x 7x   7x 7x 7x   11x 7x 7x 7x 7x 7x 7x 7x 7x 7x 6x 6x 7x   11x 7x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 1x 1x 6x 7x 11x   27x 27x 27x 27x 27x  
import { App, Modal } from "obsidian";
import type LilbeePlugin from "../main";
import type { CatalogEntry } from "../types";
import { MESSAGES } from "../locales/en";
import { renderModelDetail } from "../components/model-detail";
import { bindEscapeToClose, formatAbbreviatedCount } from "../utils";
 
interface ContextWindowField {
    context_window?: number;
}
 
interface QuantizationField {
    quantization?: string;
}
 
export class ModelInfoModal extends Modal {
    private entry: CatalogEntry;
 
    constructor(app: App, _plugin: LilbeePlugin, entry: CatalogEntry) {
        super(app);
        this.entry = entry;
        bindEscapeToClose(this);
    }
 
    onOpen(): void {
        const { contentEl } = this;
        contentEl.empty();
        contentEl.addClass("lilbee-model-info-modal");
 
        contentEl.createEl("h2", { text: MESSAGES.MODEL_INFO_TITLE });
        const detailHost = contentEl.createDiv({ cls: "lilbee-model-info-detail" });
        renderModelDetail(this.entry, detailHost);
 
        this.renderMoreInfo(contentEl);
        this.renderHfLink(contentEl);
    }
 
    private renderMoreInfo(parent: HTMLElement): void {
        const section = parent.createDiv({ cls: "lilbee-model-info-section" });
        addRow(section, MESSAGES.MODEL_INFO_TASK, this.entry.task);
        if (this.entry.param_count) addRow(section, MESSAGES.MODEL_INFO_PARAMS, this.entry.param_count);
        const ctx = (this.entry as CatalogEntry & ContextWindowField).context_window;
        if (typeof ctx === "number" && ctx > 0) addRow(section, MESSAGES.MODEL_INFO_CONTEXT, String(ctx));
        if (this.entry.min_ram_gb > 0) addRow(section, MESSAGES.MODEL_INFO_RAM, `${this.entry.min_ram_gb} GB`);
        const quant = (this.entry as CatalogEntry & QuantizationField).quantization;
        if (typeof quant === "string" && quant.length > 0) addRow(section, MESSAGES.MODEL_INFO_QUANT, quant);
        if (this.entry.downloads > 0) {
            addRow(section, MESSAGES.MODEL_INFO_DOWNLOADS, formatAbbreviatedCount(this.entry.downloads));
        }
    }
 
    private renderHfLink(parent: HTMLElement): void {
        if (!this.entry.hf_repo) return;
        const linkRow = parent.createDiv({ cls: "lilbee-model-info-link-row" });
        const url = `https://huggingface.co/${this.entry.hf_repo}`;
        const link = linkRow.createEl("a", {
            cls: "lilbee-hf-link",
            text: MESSAGES.MODEL_INFO_HF_LINK_LABEL,
        });
        link.setAttribute("href", url);
        link.setAttribute("target", "_blank");
        link.setAttribute("rel", "noopener noreferrer");
        link.addEventListener("click", (e: Event) => {
            e.preventDefault();
            window.open(url, "_blank");
        });
    }
}
 
function addRow(parent: HTMLElement, label: string, value: string): void {
    const row = parent.createDiv({ cls: "lilbee-model-info-row" });
    row.createEl("span", { cls: "lilbee-model-info-label", text: label });
    row.createEl("span", { cls: "lilbee-model-info-value", text: value });
}