Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lure: individualized links #3892

Merged
merged 13 commits into from
Sep 11, 2024
4 changes: 3 additions & 1 deletion apps/tlon-web/src/logic/branch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ export const createDeepLink = async (
}
}

const alias = path.replace('~', '').replace('/', '-');
const parsedURL = new URL(fallbackUrl);
const token = parsedURL.pathname.split('/').pop();
const alias = token || path.replace('~', '').replace('/', '-');
const data: DeepLinkData = {
$desktop_url: fallbackUrl,
$canonical_url: fallbackUrl,
Expand Down
33 changes: 18 additions & 15 deletions apps/tlon-web/src/state/lure/lure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
createStorageKey,
getFlagParts,
storageVersion,
stringToTa,
} from '@/logic/utils';

import { useLocalState } from '../local';
Expand Down Expand Up @@ -69,12 +70,11 @@ export const useLureState = create<LureState>(
bait: null,
lures: {},
describe: async (flag, metadata) => {
const { name } = getFlagParts(flag);
await api.poke({
app: 'reel',
mark: 'reel-describe',
json: {
token: name,
token: flag,
metadata,
},
});
Expand All @@ -90,7 +90,7 @@ export const useLureState = create<LureState>(
app: 'reel',
mark: 'reel-undescribe',
json: {
token: getFlagParts(flag).name,
token: flag,
},
});
} else {
Expand Down Expand Up @@ -127,7 +127,6 @@ export const useLureState = create<LureState>(
);
},
fetchLure: async (flag) => {
const { name } = getFlagParts(flag);
const prevLure = get().lures[flag];
const [enabled, url, metadata, outstandingPoke] = await Promise.all([
// enabled
Expand All @@ -149,11 +148,10 @@ export const useLureState = create<LureState>(
asyncWithDefault(() => {
lureLogger.log(performance.now(), 'fetching url', flag);
return api
.subscribeOnce<string>(
'reel',
`/token-link/${flag}`,
LURE_REQUEST_TIMEOUT
)
.scry<string>({
app: 'reel',
path: `/v1/id-url/${flag}`,
})
.then((u) => {
lureLogger.log(performance.now(), 'url fetched', flag);
return u;
Expand All @@ -164,7 +162,7 @@ export const useLureState = create<LureState>(
() =>
api.scry<LureMetadata>({
app: 'reel',
path: `/metadata/${name}`,
path: `/v1/metadata/${flag}`,
}),
prevLure?.metadata
),
Expand Down Expand Up @@ -248,14 +246,19 @@ export function useLure(flag: string, disableLoading = false) {
};
}

export function useLureLinkChecked(flag: string, enabled: boolean) {
export function useLureLinkChecked(url: string, enabled: boolean) {
const prevData = useRef<boolean | undefined>(false);
const pathEncodedUrl = stringToTa(url);
const { data, ...query } = useQuery(
['lure-check', flag],
['lure-check', url],
() =>
asyncWithDefault(
() =>
api.subscribeOnce<boolean>('grouper', `/check-link/${flag}`, 4500),
api.subscribeOnce<boolean>(
'grouper',
`/v1/check-link/${pathEncodedUrl}`,
4500
),
prevData.current ?? false
),
{
Expand All @@ -274,9 +277,9 @@ export function useLureLinkChecked(flag: string, enabled: boolean) {
}

export function useLureLinkStatus(flag: string) {
const { supported, fetched, enabled, enableAcked, url, deepLinkUrl, toggle } =
const { supported, fetched, enabled, url, deepLinkUrl, toggle } =
useLure(flag);
const { good, checked } = useLureLinkChecked(flag, !!enabled);
const { good, checked } = useLureLinkChecked(url, !!enabled);

const status = useMemo(() => {
if (!supported) {
Expand Down
82 changes: 61 additions & 21 deletions desk/app/grouper.hoon
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/- reel, groups
/+ default-agent, verb, dbug
/- reel, groups, c=chat, ch=channels
/+ gj=groups-json, default-agent, verb, dbug
::
|%
++ dev-mode |
Expand Down Expand Up @@ -36,39 +36,50 @@
^- (quip card _this)
?+ mark (on-poke:def mark vase)
%leave :_ this ~[[%pass /bite-wire %agent [our.bowl %reel] %leave ~]]
%watch
:_ this
::
%watch
:_ this
?: (~(has by wex.bowl) [/bite-wire our.bowl %reel]) ~
~[(bite-subscribe bowl)]
::
::
%grouper-enable
=+ !<(name=cord vase)
`this(enabled-groups (~(put in enabled-groups) name))
::
%grouper-disable
=+ !<(name=cord vase)
`this(enabled-groups (~(del in enabled-groups) name))
::
%grouper-ask-enabled
=+ !<(name=cord vase)
=/ enabled (~(has in enabled-groups) name)
:_ this
~[[%pass [%ask name ~] %agent [src.bowl %grouper] %poke %grouper-answer-enabled !>([name enabled])]]
::
%grouper-answer-enabled
=/ [name=cord enabled=?] !<([cord ?] vase)
:_ this
~[[%give %fact ~[[%group-enabled (scot %p src.bowl) name ~]] %json !>(b+enabled)]]
::
%grouper-check-link
=+ !<(=path vase)
?> ?=([%check-link @ @ ~] path)
=+ !<(=(pole knot) vase)
?> ?=([%check-link rest=*] pole)
=/ baseurl .^(cord %gx /(scot %p our.bowl)/reel/(scot %da now.bowl)/service/noun)
=/ target=ship (slav %p i.t.path)
=/ group=cord i.t.t.path
:: it really is necessary to double-encode this, make sure we strip
:: the leading slash before encoding
=/ end (en-urlt:html (en-urlt:html +:(spud rest.pole)))
=/ url
?. =(baseurl 'https://tlon.network/lure/')
(crip "{(trip baseurl)}{end}")
(crip "https://tlon.network/v1/policies/lure/{end}")
arthyn marked this conversation as resolved.
Show resolved Hide resolved
:_ this
:~ :* %pass path
:~ :* %pass pole
%arvo %k %fard
q.byk.bowl %lure-check-link %noun
!>(`[baseurl target group path])
!>(`[url pole])
==
==
::
%grouper-link-checked
=+ !<([good=? =path] vase)
:_ this
Expand All @@ -88,9 +99,20 @@
:~ [%pass path %agent [target %grouper] %poke %grouper-ask-enabled !>(group)]
[%pass /expire/(scot %p our.bowl)/[group] %arvo %b [%wait (add ~h1 now.bowl)]]
==
::
[%check-link @ @ ~]
:_ this
~[[%pass path %agent [our.bowl %grouper] %poke %grouper-check-link !>(path)]]
::
[%v1 %check-link @ ~]
=/ url (slav %t i.t.t.path)
:_ this
:~ :* %pass path
%arvo %k %fard
q.byk.bowl %lure-check-link %noun
!>(`[url path])
==
==
==
::
++ on-agent
Expand All @@ -104,30 +126,48 @@
?- -.sign
%poke-ack `this
%watch-ack `this
%kick
%kick
:_ this
~[(bite-subscribe bowl)]
::
%fact
=+ !<(=bite:reel q.cage.sign)
~? dev-mode [bite (~(has in enabled-groups) token.bite)]
?> (~(has in enabled-groups) token.bite)
?> ?=([%bite-1 *] bite)
arthyn marked this conversation as resolved.
Show resolved Hide resolved
~? dev-mode 'inviting'
=/ =invite:groups [[our.bowl token.bite] joiner.bite]
?> ?=([%bite-2 *] bite)
:_ this
=/ our (scot %p our.bowl)
=/ =path /[our]/groups/(scot %da now.bowl)/groups/[our]/[token.bite]/noun
=; caz=(list card)
=/ wir=^wire /dm/(scot %p joiner.bite)
=/ =dock [our.bowl %chat]
=/ =id:c [our now]:bowl
=/ =memo:ch
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fwiw, you could've done memo:d:c here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤯

[~[[%inline ~[[%ship joiner.bite] ' has joined the network']]] id]
=/ =action:dm:c
:- joiner.bite
[id %add memo [%notice ~] ~]
=/ =cage chat-dm-action+!>(`action:dm:c`action)
(snoc caz [%pass wir %agent dock %poke cage])
?~ group=(~(get by fields.metadata.bite) 'group')
~&("no group field for token: {<token.bite>}" ~)
=/ =flag:groups (flag:dejs:gj s+u.group)
~? dev-mode [bite (~(has in enabled-groups) q.flag)]
?. (~(has in enabled-groups) q.flag)
~&("group lure not enabled: {<flag>}" ~)
~? dev-mode 'inviting'
=/ =invite:groups [flag joiner.bite]
=/ prefix /(scot %p our.bowl)/groups/(scot %da now.bowl)
=+ .^(groups-running=? %gu (weld prefix /$))
?. groups-running
~&("groups not running" ~)
=/ =path (weld prefix /groups/(scot %p p.flag)/[q.flag]/noun)
=+ .^(=group:groups %gx path)
arthyn marked this conversation as resolved.
Show resolved Hide resolved
~? dev-mode cordon.group
?+ -.cordon.group ~
%open
~? dev-mode ['inviting to public' joiner.bite]
~? dev-mode ['inviting to public' joiner.bite]
~[[%pass /invite %agent [our.bowl %groups] %poke %group-invite !>(invite)]]
::
%shut
~? dev-mode ['inviting to private/secret' joiner.bite]
=/ =action:groups
=/ =action:groups
:- [our.bowl token.bite]
:- now.bowl
:- %cordon
Expand Down
4 changes: 4 additions & 0 deletions desk/sur/reel.hoon
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@
+$ bite
$% [%bite-0 token=@ta ship=@p]
[%bite-1 token=@ta joiner=@p inviter=@p]
[%bite-2 =token joiner=@p =metadata]
==
::
+$ token cord
+$ nonce @ta
+$ metadata [tag=term fields=(map cord cord)]
+$ confirmation [=nonce =token]
arthyn marked this conversation as resolved.
Show resolved Hide resolved
--
43 changes: 14 additions & 29 deletions desk/ted/lure-check-link.hoon
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,17 @@
=, strand-fail=strand-fail:libstrand:spider
^- thread:spider
=/ m (strand ,vase)
|^ ted
++ ted
|= arg=vase
^- form:m
;< our=@p bind:m get-our
=/ arguments !<((unit [cord ship cord path]) arg)
=/ [baseurl=cord target=ship group=cord =path] (need arguments)
=/ target-tape (trip (scot %p target))
?~ target-tape !!
;< ~ bind:m (send-request %'GET' (url baseurl target group) ~ ~)
;< rep=client-response:iris bind:m
take-client-response
?> ?=(%finished -.rep)
=/ result =(200 status-code.response-header.rep)
;< ~ bind:m (poke [our %grouper] grouper-link-checked+!>([result path]))
(pure:m !>(~))
++ url
|= [baseurl=cord target=ship group=cord]
^- cord
=/ target-tape (trip (scot %p target))
?~ target-tape
~& "lure link check: bad target ship"
!!
?. =(baseurl 'https://tlon.network/lure/')
(crip "{(trip baseurl)}{target-tape}/{(trip group)}")
:: it really is necessary to double-encode this
=/ end (en-urlt:html "%7E{t.target-tape}%2F{(trip group)}")
(crip "https://tlon.network/v1/policies/lure/{end}")
--
|= arg=vase
^- form:m
;< our=@p bind:m get-our
=+ !<(args=(unit [url=cord =path]) arg)
?~ args (pure:m !>(~))
=/ [url=cord =path] u.args
;< ~ bind:m (send-request %'GET' url ~ ~)
;< rep=client-response:iris bind:m
take-client-response
?> ?=(%finished -.rep)
=/ result =(200 status-code.response-header.rep)
;< ~ bind:m (poke [our %grouper] grouper-link-checked+!>([result path]))
::TODO make %grouper handle thread result
(pure:m !>(~))
5 changes: 4 additions & 1 deletion packages/shared/src/logic/branch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,10 @@ export const createDeepLink = async (
return undefined;
}
}
const alias = path.replace('~', '').replace('/', '-');

const parsedURL = new URL(fallbackUrl);
const token = parsedURL.pathname.split('/').pop();
const alias = token || path.replace('~', '').replace('/', '-');
const data: DeepLinkData = {
$desktop_url: fallbackUrl,
$canonical_url: fallbackUrl,
Expand Down
18 changes: 7 additions & 11 deletions packages/shared/src/store/lure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,11 @@ export const useLureState = create<LureState>((set, get) => ({
bait: null,
lures: {},
describe: async (flag, metadata, branchDomain, branchKey) => {
const { name } = getFlagParts(flag);
await poke({
app: 'reel',
mark: 'reel-describe',
json: {
token: name,
token: flag,
metadata,
},
});
Expand All @@ -92,7 +91,7 @@ export const useLureState = create<LureState>((set, get) => ({
app: 'reel',
mark: 'reel-undescribe',
json: {
token: getFlagParts(flag).name,
token: flag,
},
});
} else {
Expand Down Expand Up @@ -151,13 +150,10 @@ export const useLureState = create<LureState>((set, get) => ({
// url
asyncWithDefault(async () => {
lureLogger.log(performance.now(), 'fetching url', flag);
return subscribeOnce<string>(
{
app: 'reel',
path: `/token-link/${flag}`,
},
LURE_REQUEST_TIMEOUT
).then((u) => {
return scry<string>({
app: 'reel',
path: `/v1/id-url/${flag}`,
}).then((u) => {
lureLogger.log(performance.now(), 'url fetched', u, flag);
return u;
});
Expand All @@ -167,7 +163,7 @@ export const useLureState = create<LureState>((set, get) => ({
async () =>
scry<LureMetadata>({
app: 'reel',
path: `/metadata/${name}`,
path: `/metadata/${flag}`,
}),
prevLure?.metadata
),
Expand Down