mirror of
https://github.com/cheeaun/phanpy.git
synced 2025-02-02 14:16:39 +01:00
More media-first adjustments
This commit is contained in:
parent
7be620808f
commit
260bb8746d
2 changed files with 157 additions and 141 deletions
|
@ -21,6 +21,7 @@ import pmem from '../utils/pmem';
|
|||
import showToast from '../utils/show-toast';
|
||||
import states from '../utils/states';
|
||||
import { saveStatus } from '../utils/states';
|
||||
import { isMediaFirstInstance } from '../utils/store-utils';
|
||||
import useTitle from '../utils/useTitle';
|
||||
|
||||
const LIMIT = 20;
|
||||
|
@ -68,6 +69,8 @@ function AccountStatuses() {
|
|||
searchOffsetRef.current = 0;
|
||||
}, allSearchParams);
|
||||
|
||||
const mediaFirst = useMemo(() => isMediaFirstInstance(), []);
|
||||
|
||||
const sameCurrentInstance = useMemo(
|
||||
() => instance === currentInstance,
|
||||
[instance, currentInstance],
|
||||
|
@ -186,7 +189,7 @@ function AccountStatuses() {
|
|||
limit: LIMIT,
|
||||
exclude_replies: excludeReplies,
|
||||
exclude_reblogs: excludeBoosts,
|
||||
only_media: media,
|
||||
only_media: media || undefined,
|
||||
tagged,
|
||||
});
|
||||
}
|
||||
|
@ -270,17 +273,21 @@ function AccountStatuses() {
|
|||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
try {
|
||||
const featuredTags = await masto.v1.accounts
|
||||
.$select(id)
|
||||
.featuredTags.list();
|
||||
console.log({ featuredTags });
|
||||
setFeaturedTags(featuredTags);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
// No need, because the whole filter bar is hidden
|
||||
// TODO: Revisit this
|
||||
if (!mediaFirst) {
|
||||
try {
|
||||
const featuredTags = await masto.v1.accounts
|
||||
.$select(id)
|
||||
.featuredTags.list();
|
||||
console.log({ featuredTags });
|
||||
setFeaturedTags(featuredTags);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
})();
|
||||
}, [id]);
|
||||
}, [id, mediaFirst]);
|
||||
|
||||
const { displayName, acct, emojis } = account || {};
|
||||
|
||||
|
@ -299,95 +306,126 @@ function AccountStatuses() {
|
|||
authenticated={authenticated}
|
||||
standalone
|
||||
/>
|
||||
<div
|
||||
class="filter-bar"
|
||||
ref={filterBarRef}
|
||||
style={{
|
||||
position: 'relative',
|
||||
}}
|
||||
>
|
||||
{filtered ? (
|
||||
{!mediaFirst && (
|
||||
<div
|
||||
class="filter-bar"
|
||||
ref={filterBarRef}
|
||||
style={{
|
||||
position: 'relative',
|
||||
}}
|
||||
>
|
||||
{filtered ? (
|
||||
<Link
|
||||
to={`/${instance}/a/${id}`}
|
||||
class="insignificant filter-clear"
|
||||
title="Clear filters"
|
||||
key="clear-filters"
|
||||
>
|
||||
<Icon icon="x" size="l" />
|
||||
</Link>
|
||||
) : (
|
||||
<Icon icon="filter" class="insignificant" size="l" />
|
||||
)}
|
||||
<Link
|
||||
to={`/${instance}/a/${id}`}
|
||||
class="insignificant filter-clear"
|
||||
title="Clear filters"
|
||||
key="clear-filters"
|
||||
>
|
||||
<Icon icon="x" size="l" />
|
||||
</Link>
|
||||
) : (
|
||||
<Icon icon="filter" class="insignificant" size="l" />
|
||||
)}
|
||||
<Link
|
||||
to={`/${instance}/a/${id}${excludeReplies ? '?replies=1' : ''}`}
|
||||
onClick={() => {
|
||||
if (excludeReplies) {
|
||||
showToast('Showing post with replies');
|
||||
}
|
||||
}}
|
||||
class={excludeReplies ? '' : 'is-active'}
|
||||
>
|
||||
+ Replies
|
||||
</Link>
|
||||
<Link
|
||||
to={`/${instance}/a/${id}${excludeBoosts ? '' : '?boosts=0'}`}
|
||||
onClick={() => {
|
||||
if (!excludeBoosts) {
|
||||
showToast('Showing posts without boosts');
|
||||
}
|
||||
}}
|
||||
class={!excludeBoosts ? '' : 'is-active'}
|
||||
>
|
||||
- Boosts
|
||||
</Link>
|
||||
<Link
|
||||
to={`/${instance}/a/${id}${media ? '' : '?media=1'}`}
|
||||
onClick={() => {
|
||||
if (!media) {
|
||||
showToast('Showing posts with media');
|
||||
}
|
||||
}}
|
||||
class={media ? 'is-active' : ''}
|
||||
>
|
||||
Media
|
||||
</Link>
|
||||
{featuredTags.map((tag) => (
|
||||
<Link
|
||||
key={tag.id}
|
||||
to={`/${instance}/a/${id}${
|
||||
tagged === tag.name
|
||||
? ''
|
||||
: `?tagged=${encodeURIComponent(tag.name)}`
|
||||
}`}
|
||||
to={`/${instance}/a/${id}${excludeReplies ? '?replies=1' : ''}`}
|
||||
onClick={() => {
|
||||
if (tagged !== tag.name) {
|
||||
showToast(`Showing posts tagged with #${tag.name}`);
|
||||
if (excludeReplies) {
|
||||
showToast('Showing post with replies');
|
||||
}
|
||||
}}
|
||||
class={tagged === tag.name ? 'is-active' : ''}
|
||||
class={excludeReplies ? '' : 'is-active'}
|
||||
>
|
||||
<span>
|
||||
<span class="more-insignificant">#</span>
|
||||
{tag.name}
|
||||
</span>
|
||||
{
|
||||
// The count differs based on instance 😅
|
||||
}
|
||||
{/* <span class="filter-count">{tag.statusesCount}</span> */}
|
||||
+ Replies
|
||||
</Link>
|
||||
))}
|
||||
{searchEnabled &&
|
||||
(supportsInputMonth ? (
|
||||
<label class={`filter-field ${month ? 'is-active' : ''}`}>
|
||||
<Icon icon="month" size="l" />
|
||||
<input
|
||||
type="month"
|
||||
<Link
|
||||
to={`/${instance}/a/${id}${excludeBoosts ? '' : '?boosts=0'}`}
|
||||
onClick={() => {
|
||||
if (!excludeBoosts) {
|
||||
showToast('Showing posts without boosts');
|
||||
}
|
||||
}}
|
||||
class={!excludeBoosts ? '' : 'is-active'}
|
||||
>
|
||||
- Boosts
|
||||
</Link>
|
||||
<Link
|
||||
to={`/${instance}/a/${id}${media ? '' : '?media=1'}`}
|
||||
onClick={() => {
|
||||
if (!media) {
|
||||
showToast('Showing posts with media');
|
||||
}
|
||||
}}
|
||||
class={media ? 'is-active' : ''}
|
||||
>
|
||||
Media
|
||||
</Link>
|
||||
{featuredTags.map((tag) => (
|
||||
<Link
|
||||
key={tag.id}
|
||||
to={`/${instance}/a/${id}${
|
||||
tagged === tag.name
|
||||
? ''
|
||||
: `?tagged=${encodeURIComponent(tag.name)}`
|
||||
}`}
|
||||
onClick={() => {
|
||||
if (tagged !== tag.name) {
|
||||
showToast(`Showing posts tagged with #${tag.name}`);
|
||||
}
|
||||
}}
|
||||
class={tagged === tag.name ? 'is-active' : ''}
|
||||
>
|
||||
<span>
|
||||
<span class="more-insignificant">#</span>
|
||||
{tag.name}
|
||||
</span>
|
||||
{
|
||||
// The count differs based on instance 😅
|
||||
}
|
||||
{/* <span class="filter-count">{tag.statusesCount}</span> */}
|
||||
</Link>
|
||||
))}
|
||||
{searchEnabled &&
|
||||
(supportsInputMonth ? (
|
||||
<label class={`filter-field ${month ? 'is-active' : ''}`}>
|
||||
<Icon icon="month" size="l" />
|
||||
<input
|
||||
type="month"
|
||||
disabled={!account?.acct}
|
||||
value={month || ''}
|
||||
min={MIN_YEAR_MONTH}
|
||||
max={new Date().toISOString().slice(0, 7)}
|
||||
onInput={(e) => {
|
||||
const { value, validity } = e.currentTarget;
|
||||
if (!validity.valid) return;
|
||||
setSearchParams(
|
||||
value
|
||||
? {
|
||||
month: value,
|
||||
}
|
||||
: {},
|
||||
);
|
||||
const [year, month] = value.split('-');
|
||||
const monthIndex = parseInt(month, 10) - 1;
|
||||
const date = new Date(year, monthIndex);
|
||||
showToast(
|
||||
`Showing posts in ${date.toLocaleString('default', {
|
||||
month: 'long',
|
||||
year: 'numeric',
|
||||
})}`,
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</label>
|
||||
) : (
|
||||
// Fallback to <select> for month and <input type="number"> for year
|
||||
<MonthPicker
|
||||
class={`filter-field ${month ? 'is-active' : ''}`}
|
||||
disabled={!account?.acct}
|
||||
value={month || ''}
|
||||
min={MIN_YEAR_MONTH}
|
||||
max={new Date().toISOString().slice(0, 7)}
|
||||
onInput={(e) => {
|
||||
const { value, validity } = e.currentTarget;
|
||||
const { value, validity } = e;
|
||||
if (!validity.valid) return;
|
||||
setSearchParams(
|
||||
value
|
||||
|
@ -396,40 +434,11 @@ function AccountStatuses() {
|
|||
}
|
||||
: {},
|
||||
);
|
||||
const [year, month] = value.split('-');
|
||||
const monthIndex = parseInt(month, 10) - 1;
|
||||
const date = new Date(year, monthIndex);
|
||||
showToast(
|
||||
`Showing posts in ${date.toLocaleString('default', {
|
||||
month: 'long',
|
||||
year: 'numeric',
|
||||
})}`,
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</label>
|
||||
) : (
|
||||
// Fallback to <select> for month and <input type="number"> for year
|
||||
<MonthPicker
|
||||
class={`filter-field ${month ? 'is-active' : ''}`}
|
||||
disabled={!account?.acct}
|
||||
value={month || ''}
|
||||
min={MIN_YEAR_MONTH}
|
||||
max={new Date().toISOString().slice(0, 7)}
|
||||
onInput={(e) => {
|
||||
const { value, validity } = e;
|
||||
if (!validity.valid) return;
|
||||
setSearchParams(
|
||||
value
|
||||
? {
|
||||
month: value,
|
||||
}
|
||||
: {},
|
||||
);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}, [
|
||||
|
@ -492,7 +501,7 @@ function AccountStatuses() {
|
|||
errorText="Unable to load posts"
|
||||
fetchItems={fetchAccountStatuses}
|
||||
useItemID
|
||||
view={media ? 'media' : undefined}
|
||||
view={media || mediaFirst ? 'media' : undefined}
|
||||
boostsCarousel={snapStates.settings.boostsCarousel}
|
||||
timelineStart={TimelineStart}
|
||||
refresh={[
|
||||
|
|
|
@ -5,7 +5,7 @@ import {
|
|||
MenuHeader,
|
||||
MenuItem,
|
||||
} from '@szhsin/react-menu';
|
||||
import { useEffect, useRef, useState } from 'preact/hooks';
|
||||
import { useEffect, useMemo, useRef, useState } from 'preact/hooks';
|
||||
import { useNavigate, useParams, useSearchParams } from 'react-router-dom';
|
||||
|
||||
import Icon from '../components/icon';
|
||||
|
@ -18,6 +18,7 @@ import { filteredItems } from '../utils/filters';
|
|||
import showToast from '../utils/show-toast';
|
||||
import states from '../utils/states';
|
||||
import { saveStatus } from '../utils/states';
|
||||
import { isMediaFirstInstance } from '../utils/store-utils';
|
||||
import useTitle from '../utils/useTitle';
|
||||
|
||||
const LIMIT = 20;
|
||||
|
@ -55,6 +56,8 @@ function Hashtags({ media: mediaView, columnMode, ...props }) {
|
|||
useTitle(title, `/:instance?/t/:hashtag`);
|
||||
const latestItem = useRef();
|
||||
|
||||
const mediaFirst = useMemo(() => isMediaFirstInstance(), []);
|
||||
|
||||
// const hashtagsIterator = useRef();
|
||||
const maxID = useRef(undefined);
|
||||
async function fetchHashtags(firstLoad) {
|
||||
|
@ -85,7 +88,7 @@ function Hashtags({ media: mediaView, columnMode, ...props }) {
|
|||
// value = filteredItems(value, 'public');
|
||||
value.forEach((item) => {
|
||||
saveStatus(item, instance, {
|
||||
skipThreading: media, // If media view, no need to form threads
|
||||
skipThreading: media || mediaFirst, // If media view, no need to form threads
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -156,7 +159,7 @@ function Hashtags({ media: mediaView, columnMode, ...props }) {
|
|||
fetchItems={fetchHashtags}
|
||||
checkForUpdates={checkForUpdates}
|
||||
useItemID
|
||||
view={media ? 'media' : undefined}
|
||||
view={media || mediaFirst ? 'media' : undefined}
|
||||
refresh={media}
|
||||
// allowFilters
|
||||
filterContext="public"
|
||||
|
@ -233,23 +236,27 @@ function Hashtags({ media: mediaView, columnMode, ...props }) {
|
|||
<MenuDivider />
|
||||
</>
|
||||
)}
|
||||
<MenuHeader className="plain">Filters</MenuHeader>
|
||||
<MenuItem
|
||||
type="checkbox"
|
||||
checked={!!media}
|
||||
onClick={() => {
|
||||
if (media) {
|
||||
searchParams.delete('media');
|
||||
} else {
|
||||
searchParams.set('media', '1');
|
||||
}
|
||||
setSearchParams(searchParams);
|
||||
}}
|
||||
>
|
||||
<Icon icon="check-circle" />{' '}
|
||||
<span class="menu-grow">Media only</span>
|
||||
</MenuItem>
|
||||
<MenuDivider />
|
||||
{!mediaFirst && (
|
||||
<>
|
||||
<MenuHeader className="plain">Filters</MenuHeader>
|
||||
<MenuItem
|
||||
type="checkbox"
|
||||
checked={!!media}
|
||||
onClick={() => {
|
||||
if (media) {
|
||||
searchParams.delete('media');
|
||||
} else {
|
||||
searchParams.set('media', '1');
|
||||
}
|
||||
setSearchParams(searchParams);
|
||||
}}
|
||||
>
|
||||
<Icon icon="check-circle" />{' '}
|
||||
<span class="menu-grow">Media only</span>
|
||||
</MenuItem>
|
||||
<MenuDivider />
|
||||
</>
|
||||
)}
|
||||
<FocusableItem className="menu-field" disabled={reachLimit}>
|
||||
{({ ref }) => (
|
||||
<form
|
||||
|
|
Loading…
Reference in a new issue