Skip to content

Commit 4324641

Browse files
committed
Add support for FEP-3b86 (Activity Intents)
1 parent c49785c commit 4324641

6 files changed

Lines changed: 85 additions & 24 deletions

File tree

renovate.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
{
22
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
3-
"extends": [
4-
"config:recommended"
5-
]
3+
"extends": ["config:recommended"]
64
}

src/NewDomain.tsx

Lines changed: 56 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ import { FormattedMessage } from "react-intl";
77
import { useTextParam } from "./utils";
88
import { clsx } from "clsx";
99

10+
interface WebfingerResponseJSON {
11+
links: {
12+
rel: string;
13+
type: string;
14+
href: string;
15+
}[];
16+
}
17+
1018
interface ServerResponseJSON {
1119
domain: string;
1220
}
@@ -36,6 +44,40 @@ const extractDomain = (str: string): string => {
3644
return value;
3745
};
3846

47+
const fetchTemplate = (
48+
domain: string,
49+
text: string,
50+
): Promise<[string, string]> => {
51+
let fallbackDomain;
52+
53+
return fetch(
54+
`https://${domain}/.well-known/webfinger?resource=${encodeURIComponent(`https://${domain}`)}`,
55+
)
56+
.then((response) => {
57+
if (!response.ok) {
58+
throw new Error("Unexpected response");
59+
}
60+
61+
// If the server is using a different domain/subdomain to serve the UI
62+
fallbackDomain = new URL(response.url).host;
63+
64+
return response.json();
65+
})
66+
.then((json: WebfingerResponseJSON) => {
67+
const link = json.links.find(
68+
({ rel }) => rel === "https://w3id.org/fep/3b86/Create",
69+
);
70+
const template =
71+
link?.template ?? `https://${fallbackDomain}/share?text={content}`;
72+
const redirectUrl = template.replace(
73+
"{content}",
74+
encodeURIComponent(text),
75+
);
76+
77+
return [template, redirectUrl];
78+
});
79+
};
80+
3981
export const NewDomain: React.FC<{ onDismiss: () => void }> = () => {
4082
const dispatch = useAppDispatch();
4183
const text = useTextParam();
@@ -118,15 +160,15 @@ export const NewDomain: React.FC<{ onDismiss: () => void }> = () => {
118160

119161
setValue(domain);
120162
setShowResults(false);
121-
122-
const redirectUrl = `https://${domain}/share?text=${encodeURIComponent(text)}`;
123-
124163
setSubmitting(true);
125-
dispatch(addDomain(domain));
126164

127-
setTimeout(() => {
128-
window.location.href = redirectUrl;
129-
}, 100);
165+
fetchTemplate(domain, text).then(([template, redirectUrl]) => {
166+
dispatch(addDomain({ domain, template }));
167+
168+
setTimeout(() => {
169+
window.location.href = redirectUrl;
170+
}, 100);
171+
});
130172
},
131173
[dispatch, text],
132174
);
@@ -141,14 +183,15 @@ export const NewDomain: React.FC<{ onDismiss: () => void }> = () => {
141183
return;
142184
}
143185

144-
const redirectUrl = `https://${domain}/share?text=${encodeURIComponent(text)}`;
145-
146186
setSubmitting(true);
147-
dispatch(addDomain(domain));
148187

149-
setTimeout(() => {
150-
window.location.href = redirectUrl;
151-
}, 100);
188+
fetchTemplate(domain, text).then(([template, redirectUrl]) => {
189+
dispatch(addDomain({ domain, template }));
190+
191+
setTimeout(() => {
192+
window.location.href = redirectUrl;
193+
}, 100);
194+
});
152195
},
153196
[dispatch, text, domain],
154197
);

src/SavedDomain.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useCallback } from "react";
2-
import { addDomain, removeDomain } from "./actions";
2+
import { clickDomain, removeDomain } from "./actions";
33
import { useAppDispatch } from "./store";
44
import DeleteIcon from "./assets/delete.svg?react";
55
import { useIntl, defineMessages } from "react-intl";
@@ -11,13 +11,14 @@ const messages = defineMessages({
1111

1212
export const SavedDomain: React.FC<{
1313
domain: string;
14-
}> = ({ domain }) => {
14+
template: string;
15+
}> = ({ domain, template }) => {
1516
const dispatch = useAppDispatch();
1617
const intl = useIntl();
1718
const text = useTextParam();
1819

1920
const handleClick = useCallback(() => {
20-
dispatch(addDomain(domain));
21+
dispatch(clickDomain(domain));
2122
}, [dispatch, domain]);
2223

2324
const handleDeleteClick = useCallback(() => {
@@ -28,7 +29,10 @@ export const SavedDomain: React.FC<{
2829
<div className="flex bg-blurple-500 hover:bg-blurple-600 text-white rounded-4xl w-full gap-2 items-center">
2930
<a
3031
className="block w-full px-5 py-4"
31-
href={`https://${domain}/share?text=${encodeURIComponent(text ?? "")}`}
32+
href={(template ?? `https://${domain}/share?text={content}`).replace(
33+
"{content}",
34+
encodeURIComponent(text ?? ""),
35+
)}
3236
onClick={handleClick}
3337
>
3438
<div className="font-bold">{domain}</div>

src/actions/index.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import { createAction } from "@reduxjs/toolkit";
2+
import type { Domain } from "../types";
23

3-
export const addDomain = createAction<string>("accounts/add");
4+
export const addDomain =
5+
createAction<Pick<Domain, "domain" | "template">>("accounts/add");
6+
7+
export const clickDomain = createAction<string>("accounts/use");
48

59
export const removeDomain = createAction<string>("accounts/remove");

src/reducers/index.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { createReducer } from "@reduxjs/toolkit";
22
import type { Domain } from "../types";
3-
import { addDomain, removeDomain } from "../actions";
3+
import { addDomain, clickDomain, removeDomain } from "../actions";
44

55
interface State {
66
domains: Domain[];
@@ -14,7 +14,7 @@ export default createReducer(initialState, (builder) => {
1414
builder
1515
.addCase(addDomain, (state, action) => {
1616
const index = state.domains.findIndex(
17-
(domain) => domain.domain === action.payload,
17+
(domain) => domain.domain === action.payload.domain,
1818
);
1919

2020
if (index !== -1) {
@@ -24,11 +24,22 @@ export default createReducer(initialState, (builder) => {
2424
}
2525

2626
state.domains.push({
27-
domain: action.payload,
27+
domain: action.payload.domain,
28+
template: action.payload.template,
2829
used: 1,
2930
lastUsed: new Date().toString(),
3031
});
3132
})
33+
.addCase(clickDomain, (state, action) => {
34+
const index = state.domains.findIndex(
35+
(domain) => domain.domain === action.payload,
36+
);
37+
38+
if (index !== -1) {
39+
state.domains[index].used += 1;
40+
state.domains[index].lastUsed = new Date().toString();
41+
}
42+
})
3243
.addCase(removeDomain, (state, action) => {
3344
state.domains = state.domains.filter(
3445
(domain) => domain.domain !== action.payload,

src/types/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ export interface Domain {
22
domain: string;
33
used: number;
44
lastUsed: string;
5+
template?: string;
56
}

0 commit comments

Comments
 (0)