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
This commit is contained in:
Lim Chee Aun 2023-02-17 17:37:31 +08:00
parent dc1a045de9
commit b06cd36b3f
3 changed files with 97 additions and 43 deletions

View file

@ -17,6 +17,12 @@ import Link from './link';
function Account({ account, instance: propInstance, onClose }) { function Account({ account, instance: propInstance, onClose }) {
const { masto, instance, authenticated } = api({ instance: propInstance }); 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 [uiState, setUIState] = useState('default');
const isString = typeof account === 'string'; const isString = typeof account === 'string';
const [info, setInfo] = useState(isString ? null : account); const [info, setInfo] = useState(isString ? null : account);
@ -86,19 +92,44 @@ function Account({ account, instance: propInstance, onClose }) {
const [relationship, setRelationship] = useState(null); const [relationship, setRelationship] = useState(null);
const [familiarFollowers, setFamiliarFollowers] = useState([]); const [familiarFollowers, setFamiliarFollowers] = useState([]);
useEffect(() => { useEffect(() => {
if (info && authenticated) { if (info) {
const currentAccount = store.session.get('currentAccount'); const currentAccount = store.session.get('currentAccount');
if (currentAccount === id) { let accountID;
// It's myself!
return;
}
setRelationshipUIState('loading');
setFamiliarFollowers([]);
(async () => { (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 = const fetchFamiliarFollowers =
masto.v1.accounts.fetchFamiliarFollowers(id); currentMasto.v1.accounts.fetchFamiliarFollowers(accountID);
try { try {
const relationships = await fetchRelationships; const relationships = await fetchRelationships;
@ -316,12 +347,11 @@ function Account({ account, instance: propInstance, onClose }) {
); );
if (yes) { if (yes) {
newRelationship = newRelationship =
await masto.v1.accounts.unfollow(id); await currentMasto.v1.accounts.unfollow(id);
} }
} else { } else {
newRelationship = await masto.v1.accounts.follow( newRelationship =
id, await currentMasto.v1.accounts.follow(id);
);
} }
if (newRelationship) setRelationship(newRelationship); if (newRelationship) setRelationship(newRelationship);
setRelationshipUIState('default'); setRelationshipUIState('default');

View file

@ -35,3 +35,19 @@
opacity: 0; opacity: 0;
pointer-events: none; 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;
}

View file

@ -40,7 +40,9 @@ function resetScrollPosition(id) {
function StatusPage() { function StatusPage() {
const { id, ...params } = useParams(); 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 navigate = useNavigate();
const snapStates = useSnapshot(states); const snapStates = useSnapshot(states);
const [statuses, setStatuses] = useState([]); const [statuses, setStatuses] = useState([]);
@ -571,34 +573,6 @@ function StatusPage() {
<Icon icon="eye-open" />{' '} <Icon icon="eye-open" />{' '}
<span>Show all sensitive content</span> <span>Show all sensitive content</span>
</MenuItem> </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> </Menu>
)} )}
<Link <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>
</div> </div>
); );