More support for Pixelfed

This commit is contained in:
Lim Chee Aun 2024-04-14 17:20:18 +08:00
parent afdfdb86da
commit 06c6360cae
5 changed files with 124 additions and 66 deletions

View file

@ -1917,7 +1917,8 @@ body > .szh-menu-container {
/* two columns only */
grid-template-columns: repeat(2, 1fr);
}
.szh-menu .menu-horizontal:has(> .szh-menu__item:only-child) {
.szh-menu .menu-horizontal:has(> .szh-menu__item:only-child),
.szh-menu .menu-horizontal:has(> .szh-menu__submenu:only-child) {
grid-template-columns: 1fr;
}
.szh-menu .menu-horizontal > .szh-menu__item:not(:only-child):first-child,

View file

@ -12,6 +12,7 @@ import safeBoundingBoxPadding from '../utils/safe-bounding-box-padding';
import states from '../utils/states';
import store from '../utils/store';
import { getCurrentAccountID } from '../utils/store-utils';
import supports from '../utils/supports';
import Avatar from './avatar';
import Icon from './icon';
@ -83,8 +84,10 @@ function NavMenu(props) {
return results;
}
const supportsLists = supports('@mastodon/lists');
const [lists, setLists] = useState([]);
useEffect(() => {
if (!supportsLists) return;
if (menuState === 'open') {
getLists().then(setLists);
}
@ -186,9 +189,11 @@ function NavMenu(props) {
<Icon icon="history2" size="l" />
<span>Catch-up</span>
</MenuLink>
<MenuLink to="/mentions">
<Icon icon="at" size="l" /> <span>Mentions</span>
</MenuLink>
{supports('@mastodon/mentions') && (
<MenuLink to="/mentions">
<Icon icon="at" size="l" /> <span>Mentions</span>
</MenuLink>
)}
<MenuLink to="/notifications">
<Icon icon="notification" size="l" /> <span>Notifications</span>
{snapStates.notificationsShowNew && (
@ -232,10 +237,12 @@ function NavMenu(props) {
)}
</SubMenu2>
) : (
<MenuLink to="/l">
<Icon icon="list" size="l" />
<span>Lists</span>
</MenuLink>
supportsLists && (
<MenuLink to="/l">
<Icon icon="list" size="l" />
<span>Lists</span>
</MenuLink>
)
)}
<MenuLink to="/b">
<Icon icon="bookmark" size="l" /> <span>Bookmarks</span>
@ -260,10 +267,12 @@ function NavMenu(props) {
<span>Followed Hashtags</span>
</MenuLink>
<MenuDivider />
<MenuLink to="/ft">
<Icon icon="filters" size="l" />
Filters
</MenuLink>
{supports('@mastodon/filters') && (
<MenuLink to="/ft">
<Icon icon="filters" size="l" />
Filters
</MenuLink>
)}
<MenuItem
onClick={() => {
states.showGenericAccounts = {

View file

@ -55,6 +55,7 @@ import states, { getStatus, saveStatus, statusKey } from '../utils/states';
import statusPeek from '../utils/status-peek';
import store from '../utils/store';
import { getCurrentAccountID } from '../utils/store-utils';
import supports from '../utils/supports';
import unfurlMastodonLink from '../utils/unfurl-link';
import useHotkeys from '../utils/useHotkeys';
import useTruncated from '../utils/useTruncated';
@ -149,6 +150,12 @@ const PostContent = memo(
},
);
const SIZE_CLASS = {
s: 'small',
m: 'medium',
l: 'large',
};
function Status({
statusID,
status,
@ -174,7 +181,11 @@ function Status({
}) {
if (skeleton) {
return (
<div class={`status skeleton ${mediaFirst ? 'status-media-first' : ''}`}>
<div
class={`status skeleton ${
mediaFirst ? 'status-media-first small' : ''
}`}
>
{!mediaFirst && <Avatar size="xxl" />}
<div class="container">
<div class="meta">
@ -640,6 +651,7 @@ function Status({
};
const bookmarkStatus = async () => {
if (!supports('@mastodon/post-bookmark')) return;
if (!sameInstance || !authenticated) {
alert(unauthInteractionErrorMessage);
return false;
@ -827,13 +839,15 @@ function Status({
: 'Like'}
</span>
</MenuItem>
<MenuItem
onClick={bookmarkStatusNotify}
className={`menu-bookmark ${bookmarked ? 'checked' : ''}`}
>
<Icon icon="bookmark" />
<span>{bookmarked ? 'Unbookmark' : 'Bookmark'}</span>
</MenuItem>
{supports('@mastodon/post-bookmark') && (
<MenuItem
onClick={bookmarkStatusNotify}
className={`menu-bookmark ${bookmarked ? 'checked' : ''}`}
>
<Icon icon="bookmark" />
<span>{bookmarked ? 'Unbookmark' : 'Bookmark'}</span>
</MenuItem>
)}
</div>
</>
)}
@ -1077,16 +1091,18 @@ function Status({
)}
{isSelf && (
<div class="menu-horizontal">
<MenuItem
onClick={() => {
states.showCompose = {
editStatus: status,
};
}}
>
<Icon icon="pencil" />
<span>Edit</span>
</MenuItem>
{supports('@mastodon/post-edit') && (
<MenuItem
onClick={() => {
states.showCompose = {
editStatus: status,
};
}}
>
<Icon icon="pencil" />
<span>Edit</span>
</MenuItem>
)}
{isSizeLarge && (
<MenuConfirm
subMenu
@ -1395,11 +1411,7 @@ function Status({
? 'status-reply-to'
: ''
} visibility-${visibility} ${_pinned ? 'status-pinned' : ''} ${
{
s: 'small',
m: 'medium',
l: 'large',
}[size]
SIZE_CLASS[size]
} ${_deleted ? 'status-deleted' : ''} ${quoted ? 'status-card' : ''} ${
isContextMenuOpen ? 'status-menu-open' : ''
} ${mediaFirst && hasMediaAttachments ? 'status-media-first' : ''}`}
@ -2160,16 +2172,18 @@ function Status({
onClick={favouriteStatus}
/>
</div>
<div class="action">
<StatusButton
checked={bookmarked}
title={['Bookmark', 'Unbookmark']}
alt={['Bookmark', 'Bookmarked']}
class="bookmark-button"
icon="bookmark"
onClick={bookmarkStatus}
/>
</div>
{supports('@mastodon/post-bookmark') && (
<div class="action">
<StatusButton
checked={bookmarked}
title={['Bookmark', 'Unbookmark']}
alt={['Bookmark', 'Bookmarked']}
class="bookmark-button"
icon="bookmark"
onClick={bookmarkStatus}
/>
</div>
)}
<Menu2
portal={{
target:

View file

@ -19,6 +19,7 @@ import pmem from '../utils/pmem';
import shortenNumber from '../utils/shorten-number';
import states from '../utils/states';
import { saveStatus } from '../utils/states';
import supports from '../utils/supports';
import useTitle from '../utils/useTitle';
const LIMIT = 20;
@ -33,6 +34,17 @@ const fetchLinks = pmem(
},
);
function fetchTrends(masto) {
if (supports('@pixelfed/trending')) {
return masto.pixelfed.v2.discover.posts.trending.list({
range: 'daily',
});
}
return masto.v1.trends.statuses.list({
limit: LIMIT,
});
}
function Trending({ columnMode, ...props }) {
const snapStates = useSnapshot(states);
const params = columnMode ? {} : useParams();
@ -48,36 +60,39 @@ function Trending({ columnMode, ...props }) {
const [hashtags, setHashtags] = useState([]);
const [links, setLinks] = useState([]);
const trendIterator = useRef();
async function fetchTrend(firstLoad) {
if (firstLoad || !trendIterator.current) {
trendIterator.current = masto.v1.trends.statuses.list({
limit: LIMIT,
});
trendIterator.current = fetchTrends(masto);
// Get hashtags
try {
const iterator = masto.v1.trends.tags.list();
const { value: tags } = await iterator.next();
console.log('tags', tags);
if (tags?.length) {
setHashtags(tags);
if (supports('@mastodon/trending-hashtags')) {
try {
const iterator = masto.v1.trends.tags.list();
const { value: tags } = await iterator.next();
console.log('tags', tags);
if (tags?.length) {
setHashtags(tags);
}
} catch (e) {
console.error(e);
}
} catch (e) {
console.error(e);
}
// Get links
try {
const { value } = await fetchLinks(masto, instance);
// 4 types available: link, photo, video, rich
// Only want links for now
const links = value?.filter?.((link) => link.type === 'link');
console.log('links', links);
if (links?.length) {
setLinks(links);
if (supports('@mastodon/trending-links')) {
try {
const { value } = await fetchLinks(masto, instance);
// 4 types available: link, photo, video, rich
// Only want links for now
const links = value?.filter?.((link) => link.type === 'link');
console.log('links', links);
if (links?.length) {
setLinks(links);
}
} catch (e) {
console.error(e);
}
} catch (e) {
console.error(e);
}
}
const results = await trendIterator.current.next();

View file

@ -4,6 +4,20 @@ import features from '../data/features.json';
import { getCurrentInstance } from './store-utils';
// Non-semver(?) UA string detection
// Can't put this inside features.json due to regex
const containPixelfed = /pixelfed/i;
const notContainPixelfed = /^(?!.*pixelfed).*$/i;
const platformFeatures = {
'@mastodon/lists': notContainPixelfed,
'@mastodon/filters': notContainPixelfed,
'@mastodon/mentions': notContainPixelfed,
'@mastodon/trending-hashtags': notContainPixelfed,
'@mastodon/trending-links': notContainPixelfed,
'@mastodon/post-bookmark': notContainPixelfed,
'@mastodon/post-edit': notContainPixelfed,
'@pixelfed/trending': containPixelfed,
};
const supportsCache = {};
function supports(feature) {
@ -11,6 +25,11 @@ function supports(feature) {
const { version, domain } = getCurrentInstance();
const key = `${domain}-${feature}`;
if (supportsCache[key]) return supportsCache[key];
if (platformFeatures[feature]) {
return (supportsCache[key] = platformFeatures[feature].test(version));
}
const range = features[feature];
if (!range) return false;
return (supportsCache[key] = satisfies(version, range, {