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 }) {
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');

View file

@ -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;
}

View file

@ -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>
);