Skip to content

Commit 66ff778

Browse files
authored
Merge pull request #20 from Percslol/main
[scramjet, chrome] misc improvements
2 parents cea44ad + edc12de commit 66ff778

26 files changed

+841
-114
lines changed

packages/chrome/src/App.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import type { Tab } from "./Tab";
55
import { BookmarksStrip } from "./components/BookmarksStrip";
66
import { Omnibar } from "./components/Omnibar/Omnibar";
77

8-
export function App(_, cx: ComponentContext) {
8+
export function App(props: {}, cx: ComponentContext) {
99
const applyTheme = () => {
1010
let theme = browser.settings.theme;
1111

@@ -45,7 +45,7 @@ export function App(_, cx: ComponentContext) {
4545
}}
4646
/>
4747
<Omnibar tab={use(browser.activetab)} />
48-
{use(browser.activetab.url, browser.settings.bookmarksPinned)
48+
{use(browser.activetab.url, browser.settings.showBookmarksBar)
4949
.map(([u, pinned]) => pinned || u.href === "puter://newtab")
5050
.andThen(<BookmarksStrip />)}
5151
<div style="border-bottom: 1px solid var(--bg20)"></div>

packages/chrome/src/Browser.tsx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ export type Settings = {
6262
startupPage: "new-tab" | "continue";
6363
defaultZoom: number;
6464
showBookmarksBar: boolean;
65-
bookmarksPinned: boolean;
6665
defaultSearchEngine:
6766
| "google"
6867
| "bing"
@@ -98,7 +97,6 @@ export class Browser extends StatefulClass {
9897
startupPage: "new-tab",
9998
defaultZoom: 100,
10099
showBookmarksBar: true,
101-
bookmarksPinned: false,
102100
defaultSearchEngine: "google",
103101
searchSuggestionsEnabled: true,
104102
blockTrackers: true,
@@ -219,11 +217,16 @@ export class Browser extends StatefulClass {
219217
state.deserialize(s);
220218
return state;
221219
});
222-
for (let detab of de.tabs) {
223-
let tab = this.newTab();
224-
tab.deserialize(detab);
225-
tab.history.justTriggeredNavigation = true;
226-
tab.history.go(0, false);
220+
221+
if (de.settings.startupPage === "continue") {
222+
for (let detab of de.tabs) {
223+
let tab = this.newTab();
224+
tab.deserialize(detab);
225+
tab.history.justTriggeredNavigation = true;
226+
tab.history.go(0, false);
227+
}
228+
} else {
229+
this.tabs[0] = this.newTab();
227230
}
228231
this.activetab = this.tabs[0];
229232
this.bookmarks = de.bookmarks.map(createState);
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
import defaultFavicon from "../../public/defaultfavicon.png";
1+
import defaultFavicon from "/defaultfavicon.png";
22

33
export const defaultFaviconUrl = defaultFavicon;

packages/chrome/src/components/BookmarkPopup.tsx

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,56 +5,44 @@ import { Input } from "./Input";
55
import { closeMenu } from "./Menu";
66
import { Button } from "./Button";
77

8-
export function BookmarkPopup(s: {
8+
export function BookmarkPopup(props: {
99
bookmark: Stateful<BookmarkEntry>;
1010
new: boolean;
1111
}) {
1212
return (
1313
<div>
14-
<div class="title">{s.new ? "Add Bookmark" : "Edit Bookmark"}</div>
14+
<div class="title">{props.new ? "Add Bookmark" : "Edit Bookmark"}</div>
1515

1616
<div class="field">
17-
<Input
18-
label="Title"
19-
value={s.bookmark.title}
20-
onInput={(e) =>
21-
(s.bookmark.title = (e.target as HTMLInputElement).value)
22-
}
23-
/>
17+
<Input label="Title" value={use(props.bookmark.title)} />
2418
</div>
2519
<div class="field">
26-
<Input
27-
label="URL"
28-
value={s.bookmark.url}
29-
onInput={(e) =>
30-
(s.bookmark.url = (e.target as HTMLInputElement).value)
31-
}
32-
/>
20+
<Input label="URL" value={use(props.bookmark.url)} />
3321
</div>
3422
<div class="actions">
3523
<Button
3624
on:click={() => {
37-
if (!s.new) {
25+
if (!props.new) {
3826
browser.bookmarks = browser.bookmarks.filter(
39-
(b) => b !== s.bookmark
27+
(b) => b !== props.bookmark
4028
);
4129
}
4230
closeMenu();
4331
}}
4432
>
45-
{s.new ? "Cancel" : "Delete"}
33+
{props.new ? "Cancel" : "Delete"}
4634
</Button>
4735
<Button
4836
variant="primary"
4937
on:click={() => {
50-
if (s.new) {
51-
browser.bookmarks = [s.bookmark, ...browser.bookmarks];
38+
if (props.new) {
39+
browser.bookmarks = [props.bookmark, ...browser.bookmarks];
5240
}
5341

5442
closeMenu();
5543
}}
5644
>
57-
{s.new ? "Add" : "Save"}
45+
{props.new ? "Add" : "Save"}
5846
</Button>
5947
</div>
6048
</div>

packages/chrome/src/components/BookmarksStrip.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { browser, type BookmarkEntry } from "../Browser";
55
import { createMenu, createMenuCustom, setContextMenu } from "./Menu";
66
import { BookmarkPopup } from "./BookmarkPopup";
77

8-
export function BookmarksStrip(_, cx: ComponentContext) {
8+
export function BookmarksStrip(props: {}, cx: ComponentContext) {
99
cx.mount = () => {
1010
setContextMenu(cx.root, [
1111
{
@@ -15,11 +15,11 @@ export function BookmarksStrip(_, cx: ComponentContext) {
1515
},
1616
{
1717
label: "Pin Bookmarks Strip",
18-
checkbox: use(browser.settings.bookmarksPinned),
18+
checkbox: use(browser.settings.showBookmarksBar),
1919
},
2020
]);
2121
};
22-
22+
console.log(browser.bookmarks);
2323
return (
2424
<div>
2525
<button

packages/chrome/src/components/Omnibar/Suggestion.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { css } from "dreamland/core";
2-
import type { OmniboxResult } from "./suggestions";
2+
import { type OmniboxResult, AVAILABLE_SEARCH_ENGINES } from "./suggestions";
33
import { iconSearch, iconTrendingUp } from "../../icons";
4+
import { browser } from "../../Browser";
45
import { Icon } from "../Icon";
56
import { Favicon } from "../Favicon";
67
import { trimUrl } from "./utils";
@@ -72,7 +73,12 @@ export function Suggestion(props: {
7273
{item.title}
7374
<span style="font-weight: normal; opacity: 0.7">
7475
{" "}
75-
- Google Search
76+
-{" "}
77+
{
78+
AVAILABLE_SEARCH_ENGINES[browser.settings.defaultSearchEngine]
79+
.name
80+
}{" "}
81+
Search
7682
</span>
7783
</span>
7884
) : null}

packages/chrome/src/components/Omnibar/suggestions.ts

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,53 @@ export type OmniboxResult = {
1515
relevanceScore?: number;
1616
};
1717

18+
export interface SearchEngine {
19+
name: string;
20+
suggestUrlBuilder: (query: string) => string;
21+
searchUrlBuilder: (query: string) => string;
22+
suggestionParser: (data: any) => string[];
23+
}
24+
25+
/** Available search engines */
26+
export const AVAILABLE_SEARCH_ENGINES: Record<string, SearchEngine> = {
27+
google: {
28+
name: "Google",
29+
searchUrlBuilder: (query) =>
30+
`https://www.google.com/search?q=${encodeURIComponent(query)}`,
31+
suggestUrlBuilder: (query) =>
32+
`https://suggestqueries.google.com/complete/search?client=chrome&q=${encodeURIComponent(query)}`,
33+
suggestionParser: (data) => {
34+
if (Array.isArray(data) && data.length > 1 && Array.isArray(data[1])) {
35+
return data[1].map((item: any) => String(item)).filter(Boolean);
36+
}
37+
return [];
38+
},
39+
},
40+
brave: {
41+
name: "Brave",
42+
searchUrlBuilder: (query) =>
43+
`https://search.brave.com/search?q=${encodeURIComponent(query)}`,
44+
suggestUrlBuilder: (query) =>
45+
`https://search.brave.com/api/suggest?q=${encodeURIComponent(query)}&source=web`,
46+
suggestionParser: (data) => {
47+
// Google format
48+
if (Array.isArray(data) && data.length > 1 && Array.isArray(data[1])) {
49+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
50+
return data[1].map((item: any) => String(item)).filter(Boolean);
51+
}
52+
// Brave Format
53+
if (
54+
Array.isArray(data) &&
55+
data.length > 0 &&
56+
typeof data[0] === "string"
57+
) {
58+
return data.map((item: string) => String(item)).filter(Boolean);
59+
}
60+
return [];
61+
},
62+
},
63+
};
64+
1865
function calculateRelevanceScore(result: OmniboxResult, query: string): number {
1966
if (!query) return 0;
2067

@@ -130,7 +177,9 @@ const addDirectResult = (
130177
{
131178
kind: "directsearch",
132179
url: new URL(
133-
`https://www.google.com/search?q=${encodeURIComponent(query)}`
180+
AVAILABLE_SEARCH_ENGINES[
181+
browser.settings.defaultSearchEngine
182+
].searchUrlBuilder(query)
134183
),
135184
title: query,
136185
favicon: null,
@@ -147,13 +196,20 @@ const fetchGoogleSuggestions = async (
147196

148197
try {
149198
const resp = await bare.fetch(
150-
`http://suggestqueries.google.com/complete/search?client=chrome&q=${encodeURIComponent(query)}`
199+
AVAILABLE_SEARCH_ENGINES[
200+
browser.settings.defaultSearchEngine
201+
].suggestUrlBuilder(query)
151202
);
152203

153204
const json = await resp.json();
205+
let rawSuggestions =
206+
AVAILABLE_SEARCH_ENGINES[
207+
browser.settings.defaultSearchEngine
208+
].suggestionParser(json);
209+
rawSuggestions = rawSuggestions.slice(0, 5);
154210
const suggestions: OmniboxResult[] = [];
155211

156-
for (const item of json[1].slice(0, 5)) {
212+
for (const item of rawSuggestions) {
157213
// it's gonna be stuff like "http //fortnite.com/2fa ps5"
158214
// generally not useful
159215
if (item.startsWith("http")) continue;
@@ -162,7 +218,9 @@ const fetchGoogleSuggestions = async (
162218
kind: "search",
163219
title: item,
164220
url: new URL(
165-
`https://www.google.com/search?q=${encodeURIComponent(item)}`
221+
AVAILABLE_SEARCH_ENGINES[
222+
browser.settings.defaultSearchEngine
223+
].searchUrlBuilder(query)
166224
),
167225
favicon: null,
168226
});
@@ -217,6 +275,7 @@ export type TrendingQuery = {
217275

218276
export let trendingCached: TrendingQuery[] | null = null;
219277
export async function fetchGoogleTrending(geo = "US"): Promise<void> {
278+
// TODO: make this search engine agnostic
220279
try {
221280
if (trendingCached) return;
222281

packages/chrome/src/pages/AboutPage.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import { css } from "dreamland/core";
22
import type { Tab } from "../Tab";
3+
import { versionInfo } from "@mercuryworkshop/scramjet";
34

4-
export function AboutPage(s: { tab: Tab }) {
5+
export function AboutPage(props: { tab: Tab }) {
56
return (
67
<div>
78
<div class="main">
89
<h1>Puter Browser</h1>
9-
Scramjet Version: {$scramjetVersion.build} {$scramjetVersion.version}
10+
Scramjet Version: {versionInfo.version} ({versionInfo.build})
1011
</div>
1112
</div>
1213
);

packages/chrome/src/pages/DownloadsPage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { Icon } from "../components/Icon";
66
import { formatBytes } from "../utils";
77
import { defaultFaviconUrl } from "../assets/favicon";
88

9-
export function DownloadsPage(s: { tab: Tab }) {
9+
export function DownloadsPage(props: { tab: Tab }) {
1010
return (
1111
<div>
1212
<nav>

packages/chrome/src/pages/HistoryPage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type { Tab } from "../Tab";
33
import { browser } from "../Browser";
44
import { defaultFaviconUrl } from "../assets/favicon";
55

6-
export function HistoryPage(s: { tab: Tab }) {
6+
export function HistoryPage(props: { tab: Tab }) {
77
return (
88
<div>
99
<nav>

0 commit comments

Comments
 (0)