mirror of
https://github.com/cheeaun/phanpy.git
synced 2024-11-23 01:35:38 +03:00
More support for Pixelfed
This commit is contained in:
parent
afdfdb86da
commit
06c6360cae
5 changed files with 124 additions and 66 deletions
|
@ -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,
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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, {
|
||||
|
|
Loading…
Reference in a new issue