From b06cd36b3fb6f715470500c61018f00913953fd1 Mon Sep 17 00:00:00 2001 From: Lim Chee Aun <cheeaun@gmail.com> Date: Fri, 17 Feb 2023 17:37:31 +0800 Subject: [PATCH] Initial work to allow cross-instance linking - Load current-instance relationship on remote-instance account sheet - Add button to switch to current-instance status page from remote-instance status page --- src/components/account.jsx | 58 +++++++++++++++++++++++++-------- src/pages/status.css | 16 +++++++++ src/pages/status.jsx | 66 +++++++++++++++++++++----------------- 3 files changed, 97 insertions(+), 43 deletions(-) diff --git a/src/components/account.jsx b/src/components/account.jsx index a1ce0148..e24d0958 100644 --- a/src/components/account.jsx +++ b/src/components/account.jsx @@ -17,6 +17,12 @@ import Link from './link'; function Account({ account, instance: propInstance, onClose }) { const { masto, instance, authenticated } = api({ instance: propInstance }); + const { + masto: currentMasto, + instance: currentInstance, + authenticated: currentAuthenticated, + } = api(); + const sameInstance = instance === currentInstance; const [uiState, setUIState] = useState('default'); const isString = typeof account === 'string'; const [info, setInfo] = useState(isString ? null : account); @@ -86,19 +92,44 @@ function Account({ account, instance: propInstance, onClose }) { const [relationship, setRelationship] = useState(null); const [familiarFollowers, setFamiliarFollowers] = useState([]); useEffect(() => { - if (info && authenticated) { + if (info) { const currentAccount = store.session.get('currentAccount'); - if (currentAccount === id) { - // It's myself! - return; - } - setRelationshipUIState('loading'); - setFamiliarFollowers([]); - + let accountID; (async () => { - const fetchRelationships = masto.v1.accounts.fetchRelationships([id]); + if (sameInstance && authenticated) { + accountID = id; + } else if (!sameInstance && currentAuthenticated) { + // Grab this account from my logged-in instance + const acctHasInstance = info.acct.includes('@'); + try { + const results = await currentMasto.v2.search({ + q: acctHasInstance ? info.acct : `${info.username}@${instance}`, + type: 'accounts', + limit: 1, + resolve: true, + }); + console.log('🥏 Fetched account from logged-in instance', results); + accountID = results.accounts[0].id; + } catch (e) { + console.error(e); + } + } + + if (!accountID) return; + + if (currentAccount === accountID) { + // It's myself! + return; + } + + setRelationshipUIState('loading'); + setFamiliarFollowers([]); + + const fetchRelationships = currentMasto.v1.accounts.fetchRelationships([ + accountID, + ]); const fetchFamiliarFollowers = - masto.v1.accounts.fetchFamiliarFollowers(id); + currentMasto.v1.accounts.fetchFamiliarFollowers(accountID); try { const relationships = await fetchRelationships; @@ -316,12 +347,11 @@ function Account({ account, instance: propInstance, onClose }) { ); if (yes) { newRelationship = - await masto.v1.accounts.unfollow(id); + await currentMasto.v1.accounts.unfollow(id); } } else { - newRelationship = await masto.v1.accounts.follow( - id, - ); + newRelationship = + await currentMasto.v1.accounts.follow(id); } if (newRelationship) setRelationship(newRelationship); setRelationshipUIState('default'); diff --git a/src/pages/status.css b/src/pages/status.css index d40ed123..ca25dc38 100644 --- a/src/pages/status.css +++ b/src/pages/status.css @@ -35,3 +35,19 @@ opacity: 0; pointer-events: none; } + +.status-deck footer { + position: sticky; + bottom: 0; + bottom: env(safe-area-inset-bottom); + font-size: 90%; + background-color: var(--bg-faded-blur-color); + backdrop-filter: blur(16px); + padding: 16px; + white-space: pre-wrap; + line-height: 1.2; +} +.status-deck footer > p:first-of-type { + margin-top: 0; + padding-top: 0; +} diff --git a/src/pages/status.jsx b/src/pages/status.jsx index 9086aaac..12633056 100644 --- a/src/pages/status.jsx +++ b/src/pages/status.jsx @@ -40,7 +40,9 @@ function resetScrollPosition(id) { function StatusPage() { const { id, ...params } = useParams(); - const { masto, instance, authenticated } = api({ instance: params.instance }); + const { masto, instance } = api({ instance: params.instance }); + const { masto: currentMasto, instance: currentInstance } = api(); + const sameInstance = instance === currentInstance; const navigate = useNavigate(); const snapStates = useSnapshot(states); const [statuses, setStatuses] = useState([]); @@ -571,34 +573,6 @@ function StatusPage() { <Icon icon="eye-open" />{' '} <span>Show all sensitive content</span> </MenuItem> - {import.meta.env.DEV && !authenticated && ( - <MenuItem - onClick={() => { - (async () => { - try { - const { masto } = api(); - const results = await masto.v2.search({ - q: heroStatus.url, - type: 'statuses', - resolve: true, - limit: 1, - }); - if (results.statuses.length) { - const status = results.statuses[0]; - navigate(`/s/${status.id}`); - } else { - throw new Error('No results'); - } - } catch (e) { - alert('Error: ' + e); - console.error(e); - } - })(); - }} - > - See post in currently logged-in instance - </MenuItem> - )} </Menu> )} <Link @@ -756,6 +730,40 @@ function StatusPage() { )} </> )} + {!sameInstance && ( + <footer class=""> + <p> + This post is from another instance (<b>{instance}</b>), different + from your current logged-in instance (<b>{currentInstance}</b>). + </p> + <button + type="button" + onClick={() => { + (async () => { + try { + const results = await currentMasto.v2.search({ + q: heroStatus.url, + type: 'statuses', + resolve: true, + limit: 1, + }); + if (results.statuses.length) { + const status = results.statuses[0]; + navigate(`/s/${status.id}`); + } else { + throw new Error('No results'); + } + } catch (e) { + alert('Error: ' + e); + console.error(e); + } + })(); + }} + > + <Icon icon="transfer" /> Switch to my instance + </button> + </footer> + )} </div> </div> );