Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/content/inject.css
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,13 @@ table, th, td {
color: #e6e9ef !important;
}


.ultrabox-launcher-highlight {
background-color: #ffeb3b !important;
color: #111 !important;
padding: 0 2px;
border-radius: 2px;
}
.ultrabox-launcher-item-content {
color: rgba(230, 233, 239, 0.7) !important;
font-size: 0.92em;
Expand Down
82 changes: 68 additions & 14 deletions src/content/modules/launcher/display_results.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import type Fuse from "fuse.js"
import { IndexedItem } from "../../../types/indexed_item"
import { lighten } from "../../functions/lighten"
import { darken } from "../../functions/darken"
import { Settings } from "../../../types/settings"

export interface LauncherSearchResult {
item: IndexedItem
matches?: ReadonlyArray<Fuse.FuseResultMatch>
}

// Helper to promisify chrome.storage.sync.get for settings
const get_stored_settings = (): Promise<Settings | undefined> =>
new Promise(resolve => {
Expand All @@ -11,9 +17,47 @@ const get_stored_settings = (): Promise<Settings | undefined> =>
})
})

function append_highlighted_text(
container: HTMLElement,
text: string,
indices: ReadonlyArray<readonly [number, number]>
): void {
if (indices.length === 0) {
container.innerText = text
return
}

let current_index = 0

for (const [start, end] of indices) {
if (start > current_index) {
container.appendChild(document.createTextNode(text.slice(current_index, start)))
}

const highlight = document.createElement("mark")
highlight.classList.add("ultrabox-launcher-highlight")
highlight.innerText = text.slice(start, end + 1)
container.appendChild(highlight)

current_index = end + 1
}

if (current_index < text.length) {
container.appendChild(document.createTextNode(text.slice(current_index)))
}
}

function get_match_ranges(
result: LauncherSearchResult,
key_name: "item.title" | "item.content"
): ReadonlyArray<readonly [number, number]> {
const match = result.matches?.find(entry => entry.key === key_name)
return match?.indices ?? []
}

export async function display_results(
parent_div: HTMLElement,
results: IndexedItem[]
results: LauncherSearchResult[]
): Promise<void> {
const stored_settings = await get_stored_settings()
const is_dark_mode = stored_settings?.inject_css ?? false
Expand All @@ -24,26 +68,26 @@ export async function display_results(
let item_parent = document.createElement("div")
item_parent.classList.add("ultrabox-launcher-item-parent")

if (result.item.colour) {
if (result.item.item.colour) {
if (is_dark_mode) {
item_parent.style.backgroundColor = darken(result.item.colour, 0.8)
item_parent.style.backgroundColor = darken(result.item.item.colour, 0.8)
} else {
item_parent.style.backgroundColor = lighten(result.item.colour, 0.8)
item_parent.style.backgroundColor = lighten(result.item.item.colour, 0.8)
}
}

// item image
if (result.parent_channel !== "news") {
if (result.item.parent_channel !== "news") {
let item_image = document.createElement("div")
item_image.classList.add("ultrabox-launcher-item-placeholder-image")
item_image.style.backgroundColor = result.item.colour || "#a8caff"
item_image.innerText = result.item.title[0].toUpperCase()
item_image.style.backgroundColor = result.item.item.colour || "#a8caff"
item_image.innerText = result.item.item.title[0].toUpperCase()

item_parent.appendChild(item_image)
} else {
let item_image = document.createElement("img")
item_image.classList.add("ultrabox-launcher-item-image")
item_image.src = result.item.image_uri || ""
item_image.src = result.item.item.image_uri || ""
item_image.onerror = () => {
item_image.onerror = null
item_image.src = "/images/logo.php?logo=skin_logo_square&size=normal"
Expand All @@ -61,27 +105,37 @@ export async function display_results(

let item_channel = document.createElement("div")
item_channel.classList.add("ultrabox-launcher-item-channel")
item_channel.innerText = result.item.parent + " / "
item_channel.innerText = result.item.item.parent + " / "
item_title.appendChild(item_channel)

let item_title_link = document.createElement("a")
let link = null
if (result.parent_channel !== "this_textbook") {
link = new URL(result.item.link)
if (result.item.parent_channel !== "this_textbook") {
link = new URL(result.item.item.link)
link.searchParams.set("ub_ref", "launcher")
item_title_link.href = link.toString()
} else {
item_title_link.setAttribute("data-heading-name", result.item.title)
item_title_link.setAttribute("data-heading-name", result.item.item.title)
}
item_title_link.innerText = result.item.title

append_highlighted_text(
item_title_link,
result.item.item.title,
get_match_ranges(result, "item.title")
)
item_title.appendChild(item_title_link)

item_details_container.appendChild(item_title)

// content preview
let item_content = document.createElement("div")
item_content.classList.add("ultrabox-launcher-item-content")
item_content.innerText = result.item.content.slice(0, 200)
const content_preview = result.item.item.content.slice(0, 200)
const content_ranges = get_match_ranges(result, "item.content")
.map(([start, end]) => [start, Math.min(end, content_preview.length - 1)] as const)
.filter(([start, end]) => start <= end)

append_highlighted_text(item_content, content_preview, content_ranges)
item_details_container.appendChild(item_content)

// add to parent div
Expand Down
9 changes: 8 additions & 1 deletion src/content/modules/launcher/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export async function get_news_channels(): Promise<void> {
ignoreDiacritics: true,
useExtendedSearch: true,
includeScore: true,
includeMatches: true,
})
}

Expand Down Expand Up @@ -200,10 +201,16 @@ export async function on_input(ev: Event): Promise<void> {
return {
entry: result.item,
score: base_score - recency_boost - bounce_rate_boost,
matches: result.matches,
}
})
.sort((a, b) => a.score - b.score)
.map(result => result.entry)
.map(result => {
return {
item: result.entry,
matches: result.matches,
}
})

let filtered_results = weighted_results.slice(0, 8)

Expand Down