Skip to content

Commit aa6f35f

Browse files
committed
[app] Use hash to share data
1 parent 474f971 commit aa6f35f

4 files changed

Lines changed: 74 additions & 89 deletions

File tree

.changeset/lucky-olives-speak.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"web": major
3+
---
4+
5+
Use hash to share data

apps/web/src/main-page.svelte

Lines changed: 15 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import { createPage } from "./lib/browser";
2121
2222
import {
23+
createShareUrl,
2324
fetchAsText,
2425
makeSource,
2526
resolveSource,
@@ -58,46 +59,23 @@
5859
}
5960
6061
async function shareTable() {
61-
const { value } = form;
62-
if (value === undefined) {
62+
const options = form.value;
63+
if (options === undefined) {
6364
return;
6465
}
65-
const url = new URL(window.location.href);
66-
const { data } = source;
67-
if (shareBehavior === ShareBehavior.CreateOnOpen) {
68-
url.searchParams.set("createOnOpen", "true");
69-
} else {
70-
url.searchParams.delete("createOnOpen");
71-
}
72-
url.searchParams.set("options", compressor.compress(JSON.stringify(value)));
73-
url.searchParams.set("data", data && compressor.compress(data));
74-
const urlStr = url.toString();
75-
copyTextToClipboard(urlStr)
76-
.then(() => {
77-
if (urlStr.length > 2000) {
78-
window.alert("URL is too long");
79-
// toast({
80-
// title: "URL is too long",
81-
// description:
82-
// "URL is copied to clipboard, but it's too long for a browsers",
83-
// status: "warning",
84-
// });
85-
} else {
86-
window.alert("URL copied to the clipboard");
87-
// toast({
88-
// title: "URL copied to clipboard",
89-
// status: "success",
90-
// });
91-
}
92-
})
93-
.catch((err): void => {
66+
const sharedUrl = createShareUrl(compressor.compress, {
67+
data: source.data,
68+
options,
69+
createOnOpen: shareBehavior === ShareBehavior.CreateOnOpen,
70+
});
71+
copyTextToClipboard(sharedUrl).then(
72+
() => {
73+
window.alert("URL copied to the clipboard");
74+
},
75+
(): void => {
9476
window.alert("Failed to copy URL to clipboard");
95-
// toast({
96-
// title: "Failed to copy URL to clipboard",
97-
// status: "error",
98-
// description: String(err),
99-
// });
100-
});
77+
}
78+
);
10179
}
10280
10381
let theme = $state<"light" | "dark" | "system">(
@@ -128,11 +106,6 @@
128106
})
129107
.catch((e) => {
130108
window.alert(String(e));
131-
// toast({
132-
// title: "Error",
133-
// description: e,
134-
// status: "error",
135-
// });
136109
});
137110
},
138111
});

apps/web/src/main.ts

Lines changed: 37 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,9 @@ import { isValidUrl } from "./lib/url";
55
import MainPage from "./main-page.svelte";
66
import DownloadTablePage from "./download-table-page.svelte";
77
import HtmlTablePage from "./html-table-page.svelte";
8-
import {
9-
OutputFormat,
10-
type TransformConfig,
11-
TransformPreset,
12-
} from "./core";
8+
import { OutputFormat, type TransformConfig, TransformPreset } from "./core";
139
import { compressor, appWorker } from "./init";
14-
import { fetchAsText } from "./model";
10+
import { fetchAsText, type SharedData } from "./model";
1511
import "./app.css";
1612

1713
const target = document.getElementById("app")!;
@@ -24,48 +20,43 @@ function page() {
2420
format: OutputFormat.HTML,
2521
paginate: false,
2622
};
27-
const searchParams = new URLSearchParams(window.location.search);
28-
if (searchParams.has("data")) {
29-
try {
30-
initialData = compressor.decompress(searchParams.get("data")!) || "";
31-
} catch (error) {
32-
console.error(error);
23+
const hash = location.hash.substring(1);
24+
if (hash !== "") {
25+
const { data, options, createOnOpen }: SharedData = JSON.parse(
26+
compressor.decompress(hash)
27+
);
28+
if (data) {
29+
initialData = data;
3330
}
34-
}
35-
if (searchParams.has("options")) {
36-
try {
37-
initialOptions = JSON.parse(
38-
compressor.decompress(searchParams.get("options")!)
39-
);
40-
} catch (error) {
41-
console.error(error);
31+
if (options) {
32+
initialOptions = options;
4233
}
43-
}
44-
if (searchParams.get("createOnOpen") === "true") {
45-
const table = isValidUrl(initialData)
46-
? fetchAsText(initialData).then((data) =>
47-
appWorker.createTable({ data, config: initialOptions })
48-
)
49-
: appWorker.createTable({
50-
data: initialData,
51-
config: initialOptions,
52-
});
53-
switch (initialOptions.format) {
54-
case OutputFormat.XLSX:
55-
return mount(DownloadTablePage, {
56-
target,
57-
props: {
58-
title: "table.xlsx",
59-
content: table,
60-
},
61-
});
62-
default:
63-
return mount(HtmlTablePage, {
64-
target,
65-
props: {
66-
content: table,
67-
},
68-
});
34+
if (createOnOpen) {
35+
const table = isValidUrl(initialData)
36+
? fetchAsText(initialData).then((data) =>
37+
appWorker.createTable({ data, config: initialOptions })
38+
)
39+
: appWorker.createTable({
40+
data: initialData,
41+
config: initialOptions,
42+
});
43+
switch (initialOptions.format) {
44+
case OutputFormat.XLSX:
45+
return mount(DownloadTablePage, {
46+
target,
47+
props: {
48+
title: "table.xlsx",
49+
content: table,
50+
},
51+
});
52+
default:
53+
return mount(HtmlTablePage, {
54+
target,
55+
props: {
56+
content: table,
57+
},
58+
});
59+
}
6960
}
7061
}
7162
return mount(MainPage, {

apps/web/src/model.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,13 @@ import {
55
ASCII_TABLE_FORMATS,
66
} from "@json-table/core/block-to-ascii";
77

8-
import { OutputFormat, TransformPreset } from "./core";
8+
import { OutputFormat, TransformPreset, type TransformConfig } from "./core";
9+
10+
export interface SharedData {
11+
data: string;
12+
options: TransformConfig;
13+
createOnOpen: boolean;
14+
}
915

1016
export enum ShareBehavior {
1117
CreateOnOpen = "createOnOpen",
@@ -33,6 +39,16 @@ export type Source = {
3339
}
3440
);
3541

42+
export function createShareUrl(
43+
compress: (data: string) => string,
44+
data: SharedData
45+
) {
46+
const encoded = compress(JSON.stringify(data));
47+
const url = new URL(location.href);
48+
url.hash = encoded;
49+
return url.toString();
50+
}
51+
3652
export function makeSource(type: SourceType): Source {
3753
switch (type) {
3854
case SourceType.File:

0 commit comments

Comments
 (0)