Skip to content

Commit 6cfedc7

Browse files
committed
[chrome] refactor and split UrlInput.tsx
1 parent 485b557 commit 6cfedc7

File tree

13 files changed

+446
-371
lines changed

13 files changed

+446
-371
lines changed

packages/chrome/src/App.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { Component } from "dreamland/core";
2-
import { Omnibox } from "./components/Omnibox";
2+
import { Omnibox } from "./components/Omnibar/Omnibox";
33
import { Tabs } from "./components/TabStrip";
44
import { browser } from "./Browser";
55
import type { Tab } from "./Tab";

packages/chrome/src/Browser.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@ import { Tab, type SerializedTab } from "./Tab";
44
import { createDelegate } from "dreamland/core";
55
import type { SerializedHistoryState } from "./History";
66
import { HistoryState } from "./History";
7-
import { focusOmnibox } from "./components/UrlInput";
7+
import { focusOmnibox } from "./components/Omnibar/UrlInput";
88

99
import * as tldts from "tldts";
1010
import { isPuter } from "./main";
11-
import { animateDownloadFly, showDownloadsPopup } from "./components/Omnibox";
11+
import {
12+
animateDownloadFly,
13+
showDownloadsPopup,
14+
} from "./components/Omnibar/Omnibox";
1215
export const pushTab = createDelegate<Tab>();
1316
export const popTab = createDelegate<Tab>();
1417
export const forceScreenshot = createDelegate<Tab>();
@@ -60,7 +63,7 @@ export type GlobalHistoryEntry = {
6063
export type BookmarkEntry = {
6164
url: string;
6265
title: string;
63-
favicon?: string;
66+
favicon: string | null;
6467
};
6568

6669
export type DownloadEntry = {
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { css, type Component } from "dreamland/core";
2+
import { defaultFaviconUrl } from "../assets/favicon";
3+
4+
export const Favicon: Component<{ url: string | null }> = function (cx) {
5+
return <img src={use(this.url).map((u) => u || defaultFaviconUrl)}></img>;
6+
};
7+
Favicon.style = css`
8+
:scope {
9+
width: 16px;
10+
height: 16px;
11+
}
12+
`;
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { createState, type Component } from "dreamland/core";
2+
import { OmnibarButton } from "./OmnibarButton";
3+
import { browser } from "../../Browser";
4+
import { createMenuCustom } from "../Menu";
5+
import { BookmarkPopup } from "../BookmarkPopup";
6+
import { emToPx } from "../../utils";
7+
8+
import iconStar from "@ktibow/iconset-ion/star-outline";
9+
import iconStarFilled from "@ktibow/iconset-ion/star";
10+
11+
export const BookmarkButton: Component<{
12+
url: URL;
13+
}> = function () {
14+
return (
15+
<OmnibarButton
16+
click={(e) => {
17+
e.stopPropagation();
18+
e.preventDefault();
19+
let bookmark = browser.bookmarks.find((b) => b.url == this.url.href);
20+
21+
let isnew = false;
22+
if (!bookmark) {
23+
bookmark = createState({
24+
url: browser.activetab.url.href,
25+
favicon: browser.activetab.icon,
26+
title: browser.activetab.title || browser.activetab.url.hostname,
27+
});
28+
isnew = true;
29+
}
30+
31+
createMenuCustom(
32+
{
33+
right: (e.target as HTMLElement).getBoundingClientRect().right,
34+
top: emToPx(2.5) + 40,
35+
},
36+
<BookmarkPopup new={isnew} bookmark={bookmark}></BookmarkPopup>
37+
);
38+
}}
39+
icon={use(browser.bookmarks, this.url).map(() =>
40+
browser.bookmarks.some((b) => b.url == this.url.href)
41+
? iconStarFilled
42+
: iconStar
43+
)}
44+
></OmnibarButton>
45+
);
46+
};
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { css, type Component } from "dreamland/core";
2+
3+
export const CircularProgress: Component<{
4+
progress: number;
5+
size?: string;
6+
strokeWidth?: string;
7+
color?: string;
8+
}> = function (cx) {
9+
const radius = 100;
10+
const circumference = 2 * Math.PI * radius;
11+
12+
use(this.progress).listen((p) => {
13+
if (p == 0) {
14+
cx.root.classList.remove("visible");
15+
} else {
16+
cx.root.classList.add("visible");
17+
18+
cx.root
19+
.querySelector("circle.moving")!
20+
.setAttribute("stroke-dashoffset", circumference * (1 - p) + "px");
21+
}
22+
});
23+
24+
return (
25+
<svg
26+
width="200"
27+
height="200"
28+
viewBox="0 0 200 200"
29+
version="1.1"
30+
xmlns="http://www.w3.org/2000/svg"
31+
style="transform:rotate(-90deg)"
32+
>
33+
<circle
34+
r="90"
35+
cx="100"
36+
cy="100"
37+
class="inactive"
38+
stroke-width="16px"
39+
stroke-linecap="round"
40+
stroke-dashoffset="0px"
41+
fill="transparent"
42+
stroke-dasharray="565.48px"
43+
></circle>
44+
<circle
45+
r="90"
46+
cx="100"
47+
cy="100"
48+
class="moving"
49+
stroke-width="16px"
50+
stroke-linecap="round"
51+
stroke-dashoffset="118.692px"
52+
fill="transparent"
53+
stroke-dasharray="565.48px"
54+
></circle>
55+
</svg>
56+
);
57+
};
58+
CircularProgress.style = css`
59+
:scope {
60+
pointer-events: none;
61+
position: absolute;
62+
top: 2px;
63+
left: 0;
64+
width: 100%;
65+
height: 100%;
66+
opacity: 0;
67+
transition: opacity 0.2s ease;
68+
transform: rotate(-90deg);
69+
}
70+
:scope.visible {
71+
opacity: 1;
72+
}
73+
circle {
74+
fill: transparent;
75+
stroke: var(--accent);
76+
/*transition: stroke-dashoffset 0.2s ease;*/
77+
}
78+
circle.inactive {
79+
stroke: var(--bg20);
80+
}
81+
`;

packages/chrome/src/components/OmnibarButton.tsx renamed to packages/chrome/src/components/Omnibar/OmnibarButton.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { IconifyIcon } from "@iconify/types";
22
import { css, type Component } from "dreamland/core";
3-
import { Icon } from "./Icon";
3+
import { Icon } from "../Icon";
44

55
export const OmnibarButton: Component<{
66
icon: IconifyIcon;

packages/chrome/src/components/Omnibox.tsx renamed to packages/chrome/src/components/Omnibar/Omnibox.tsx

Lines changed: 10 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,23 @@ import iconExtension from "@ktibow/iconset-ion/extension-puzzle-outline";
66
import iconDownload from "@ktibow/iconset-ion/download-outline";
77
import iconMore from "@ktibow/iconset-ion/more";
88
import iconExit from "@ktibow/iconset-ion/exit-outline";
9-
import { createMenu, createMenuCustom } from "./Menu";
9+
import { createMenu, createMenuCustom } from "../Menu";
1010
import { OmnibarButton } from "./OmnibarButton";
1111
import { createDelegate } from "dreamland/core";
12-
import type { Tab } from "../Tab";
12+
import type { Tab } from "../../Tab";
1313
import { UrlInput } from "./UrlInput";
14-
import { browser } from "../Browser";
15-
import { Icon } from "./Icon";
16-
import { defaultFaviconUrl } from "../assets/favicon";
14+
import { browser } from "../../Browser";
15+
import { Icon } from "../Icon";
16+
import { defaultFaviconUrl } from "../../assets/favicon";
1717

1818
import iconNew from "@ktibow/iconset-ion/duplicate-outline";
1919
import iconTime from "@ktibow/iconset-ion/time-outline";
2020
import iconInfo from "@ktibow/iconset-ion/information-circle-outline";
2121
import iconSettings from "@ktibow/iconset-ion/settings-outline";
22-
import type { HistoryState } from "../History";
23-
import { isPuter } from "../main";
24-
import { DownloadsPopup } from "./DownloadsPopup";
22+
import type { HistoryState } from "../../History";
23+
import { isPuter } from "../../main";
24+
import { DownloadsPopup } from "../DownloadsPopup";
25+
import { CircularProgress } from "./CircularProgress";
2526

2627
export const animateDownloadFly = createDelegate<void>();
2728
export const showDownloadsPopup = createDelegate<void>();
@@ -35,86 +36,6 @@ Spacer.style = css`
3536
}
3637
`;
3738

38-
export const CircularProgress: Component<{
39-
progress: number;
40-
size?: string;
41-
strokeWidth?: string;
42-
color?: string;
43-
}> = function (cx) {
44-
const radius = 100;
45-
const circumference = 2 * Math.PI * radius;
46-
47-
use(this.progress).listen((p) => {
48-
if (p == 0) {
49-
cx.root.classList.remove("visible");
50-
} else {
51-
cx.root.classList.add("visible");
52-
53-
cx.root
54-
.querySelector("circle.moving")!
55-
.setAttribute("stroke-dashoffset", circumference * (1 - p) + "px");
56-
}
57-
});
58-
59-
return (
60-
<svg
61-
width="200"
62-
height="200"
63-
viewBox="0 0 200 200"
64-
version="1.1"
65-
xmlns="http://www.w3.org/2000/svg"
66-
style="transform:rotate(-90deg)"
67-
>
68-
<circle
69-
r="90"
70-
cx="100"
71-
cy="100"
72-
class="inactive"
73-
stroke-width="16px"
74-
stroke-linecap="round"
75-
stroke-dashoffset="0px"
76-
fill="transparent"
77-
stroke-dasharray="565.48px"
78-
></circle>
79-
<circle
80-
r="90"
81-
cx="100"
82-
cy="100"
83-
class="moving"
84-
stroke-width="16px"
85-
stroke-linecap="round"
86-
stroke-dashoffset="118.692px"
87-
fill="transparent"
88-
stroke-dasharray="565.48px"
89-
></circle>
90-
</svg>
91-
);
92-
};
93-
CircularProgress.style = css`
94-
:scope {
95-
pointer-events: none;
96-
position: absolute;
97-
top: 2px;
98-
left: 0;
99-
width: 100%;
100-
height: 100%;
101-
opacity: 0;
102-
transition: opacity 0.2s ease;
103-
transform: rotate(-90deg);
104-
}
105-
:scope.visible {
106-
opacity: 1;
107-
}
108-
circle {
109-
fill: transparent;
110-
stroke: var(--accent);
111-
/*transition: stroke-dashoffset 0.2s ease;*/
112-
}
113-
circle.inactive {
114-
stroke: var(--bg20);
115-
}
116-
`;
117-
11839
export const Omnibox: Component<{
11940
tab: Tab;
12041
}> = function (cx) {
@@ -223,7 +144,7 @@ export const Omnibox: Component<{
223144
<Spacer></Spacer>
224145
<UrlInput
225146
selectContent={selectContent}
226-
tabUrl={use(this.tab.url)}
147+
url={use(this.tab.url)}
227148
></UrlInput>
228149
<Spacer></Spacer>
229150
<OmnibarButton active={false} icon={iconExtension}></OmnibarButton>
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { css, type Component } from "dreamland/core";
2+
import { createMenuCustom } from "../Menu";
3+
import { SiteInformationPopup } from "../SiteInformationPopup";
4+
import { browser } from "../../Browser";
5+
import { Icon } from "../Icon";
6+
import { emToPx } from "../../utils";
7+
import iconOptions from "@ktibow/iconset-ion/options-outline";
8+
9+
export const SiteOptionsButton: Component<{}> = function () {
10+
return (
11+
<button
12+
class="optionsbutton"
13+
on:click={(e: MouseEvent) => {
14+
createMenuCustom(
15+
{
16+
left: (e.target as HTMLElement).getBoundingClientRect().left,
17+
top: emToPx(2.5) + 40,
18+
},
19+
<SiteInformationPopup tab={browser.activetab}></SiteInformationPopup>
20+
);
21+
e.preventDefault();
22+
e.stopPropagation();
23+
}}
24+
>
25+
<Icon icon={iconOptions}></Icon>
26+
</button>
27+
);
28+
};
29+
SiteOptionsButton.style = css`
30+
.optionsbutton {
31+
width: 100%;
32+
cursor: pointer;
33+
padding: 0;
34+
margin: 0;
35+
background: none;
36+
outline: none;
37+
border: none;
38+
color: var(--fg);
39+
font-size: 1em;
40+
padding: 0.1em;
41+
border-radius: 0.2em;
42+
display: flex;
43+
align-items: center;
44+
justify-content: center;
45+
background: var(--bg01);
46+
}
47+
.optionsbutton:hover {
48+
background: var(--bg02);
49+
}
50+
`;

0 commit comments

Comments
 (0)