mirror of
https://github.com/cheeaun/phanpy.git
synced 2025-03-23 14:13:21 +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 showToast from '../utils/show-toast';
|
||||||
import states from '../utils/states';
|
import states from '../utils/states';
|
||||||
import { saveStatus } from '../utils/states';
|
import { saveStatus } from '../utils/states';
|
||||||
|
import { isMediaFirstInstance } from '../utils/store-utils';
|
||||||
import useTitle from '../utils/useTitle';
|
import useTitle from '../utils/useTitle';
|
||||||
|
|
||||||
const LIMIT = 20;
|
const LIMIT = 20;
|
||||||
|
@ -68,6 +69,8 @@ function AccountStatuses() {
|
||||||
searchOffsetRef.current = 0;
|
searchOffsetRef.current = 0;
|
||||||
}, allSearchParams);
|
}, allSearchParams);
|
||||||
|
|
||||||
|
const mediaFirst = useMemo(() => isMediaFirstInstance(), []);
|
||||||
|
|
||||||
const sameCurrentInstance = useMemo(
|
const sameCurrentInstance = useMemo(
|
||||||
() => instance === currentInstance,
|
() => instance === currentInstance,
|
||||||
[instance, currentInstance],
|
[instance, currentInstance],
|
||||||
|
@ -186,7 +189,7 @@ function AccountStatuses() {
|
||||||
limit: LIMIT,
|
limit: LIMIT,
|
||||||
exclude_replies: excludeReplies,
|
exclude_replies: excludeReplies,
|
||||||
exclude_reblogs: excludeBoosts,
|
exclude_reblogs: excludeBoosts,
|
||||||
only_media: media,
|
only_media: media || undefined,
|
||||||
tagged,
|
tagged,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -270,17 +273,21 @@ function AccountStatuses() {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
}
|
||||||
try {
|
// No need, because the whole filter bar is hidden
|
||||||
const featuredTags = await masto.v1.accounts
|
// TODO: Revisit this
|
||||||
.$select(id)
|
if (!mediaFirst) {
|
||||||
.featuredTags.list();
|
try {
|
||||||
console.log({ featuredTags });
|
const featuredTags = await masto.v1.accounts
|
||||||
setFeaturedTags(featuredTags);
|
.$select(id)
|
||||||
} catch (e) {
|
.featuredTags.list();
|
||||||
console.error(e);
|
console.log({ featuredTags });
|
||||||
|
setFeaturedTags(featuredTags);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
}, [id]);
|
}, [id, mediaFirst]);
|
||||||
|
|
||||||
const { displayName, acct, emojis } = account || {};
|
const { displayName, acct, emojis } = account || {};
|
||||||
|
|
||||||
|
@ -299,95 +306,126 @@ function AccountStatuses() {
|
||||||
authenticated={authenticated}
|
authenticated={authenticated}
|
||||||
standalone
|
standalone
|
||||||
/>
|
/>
|
||||||
<div
|
{!mediaFirst && (
|
||||||
class="filter-bar"
|
<div
|
||||||
ref={filterBarRef}
|
class="filter-bar"
|
||||||
style={{
|
ref={filterBarRef}
|
||||||
position: 'relative',
|
style={{
|
||||||
}}
|
position: 'relative',
|
||||||
>
|
}}
|
||||||
{filtered ? (
|
>
|
||||||
|
{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
|
<Link
|
||||||
to={`/${instance}/a/${id}`}
|
to={`/${instance}/a/${id}${excludeReplies ? '?replies=1' : ''}`}
|
||||||
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)}`
|
|
||||||
}`}
|
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (tagged !== tag.name) {
|
if (excludeReplies) {
|
||||||
showToast(`Showing posts tagged with #${tag.name}`);
|
showToast('Showing post with replies');
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
class={tagged === tag.name ? 'is-active' : ''}
|
class={excludeReplies ? '' : 'is-active'}
|
||||||
>
|
>
|
||||||
<span>
|
+ Replies
|
||||||
<span class="more-insignificant">#</span>
|
|
||||||
{tag.name}
|
|
||||||
</span>
|
|
||||||
{
|
|
||||||
// The count differs based on instance 😅
|
|
||||||
}
|
|
||||||
{/* <span class="filter-count">{tag.statusesCount}</span> */}
|
|
||||||
</Link>
|
</Link>
|
||||||
))}
|
<Link
|
||||||
{searchEnabled &&
|
to={`/${instance}/a/${id}${excludeBoosts ? '' : '?boosts=0'}`}
|
||||||
(supportsInputMonth ? (
|
onClick={() => {
|
||||||
<label class={`filter-field ${month ? 'is-active' : ''}`}>
|
if (!excludeBoosts) {
|
||||||
<Icon icon="month" size="l" />
|
showToast('Showing posts without boosts');
|
||||||
<input
|
}
|
||||||
type="month"
|
}}
|
||||||
|
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}
|
disabled={!account?.acct}
|
||||||
value={month || ''}
|
value={month || ''}
|
||||||
min={MIN_YEAR_MONTH}
|
min={MIN_YEAR_MONTH}
|
||||||
max={new Date().toISOString().slice(0, 7)}
|
max={new Date().toISOString().slice(0, 7)}
|
||||||
onInput={(e) => {
|
onInput={(e) => {
|
||||||
const { value, validity } = e.currentTarget;
|
const { value, validity } = e;
|
||||||
if (!validity.valid) return;
|
if (!validity.valid) return;
|
||||||
setSearchParams(
|
setSearchParams(
|
||||||
value
|
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>
|
))}
|
||||||
) : (
|
</div>
|
||||||
// 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>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}, [
|
}, [
|
||||||
|
@ -492,7 +501,7 @@ function AccountStatuses() {
|
||||||
errorText="Unable to load posts"
|
errorText="Unable to load posts"
|
||||||
fetchItems={fetchAccountStatuses}
|
fetchItems={fetchAccountStatuses}
|
||||||
useItemID
|
useItemID
|
||||||
view={media ? 'media' : undefined}
|
view={media || mediaFirst ? 'media' : undefined}
|
||||||
boostsCarousel={snapStates.settings.boostsCarousel}
|
boostsCarousel={snapStates.settings.boostsCarousel}
|
||||||
timelineStart={TimelineStart}
|
timelineStart={TimelineStart}
|
||||||
refresh={[
|
refresh={[
|
||||||
|
|
|
@ -5,7 +5,7 @@ import {
|
||||||
MenuHeader,
|
MenuHeader,
|
||||||
MenuItem,
|
MenuItem,
|
||||||
} from '@szhsin/react-menu';
|
} 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 { useNavigate, useParams, useSearchParams } from 'react-router-dom';
|
||||||
|
|
||||||
import Icon from '../components/icon';
|
import Icon from '../components/icon';
|
||||||
|
@ -18,6 +18,7 @@ import { filteredItems } from '../utils/filters';
|
||||||
import showToast from '../utils/show-toast';
|
import showToast from '../utils/show-toast';
|
||||||
import states from '../utils/states';
|
import states from '../utils/states';
|
||||||
import { saveStatus } from '../utils/states';
|
import { saveStatus } from '../utils/states';
|
||||||
|
import { isMediaFirstInstance } from '../utils/store-utils';
|
||||||
import useTitle from '../utils/useTitle';
|
import useTitle from '../utils/useTitle';
|
||||||
|
|
||||||
const LIMIT = 20;
|
const LIMIT = 20;
|
||||||
|
@ -55,6 +56,8 @@ function Hashtags({ media: mediaView, columnMode, ...props }) {
|
||||||
useTitle(title, `/:instance?/t/:hashtag`);
|
useTitle(title, `/:instance?/t/:hashtag`);
|
||||||
const latestItem = useRef();
|
const latestItem = useRef();
|
||||||
|
|
||||||
|
const mediaFirst = useMemo(() => isMediaFirstInstance(), []);
|
||||||
|
|
||||||
// const hashtagsIterator = useRef();
|
// const hashtagsIterator = useRef();
|
||||||
const maxID = useRef(undefined);
|
const maxID = useRef(undefined);
|
||||||
async function fetchHashtags(firstLoad) {
|
async function fetchHashtags(firstLoad) {
|
||||||
|
@ -85,7 +88,7 @@ function Hashtags({ media: mediaView, columnMode, ...props }) {
|
||||||
// value = filteredItems(value, 'public');
|
// value = filteredItems(value, 'public');
|
||||||
value.forEach((item) => {
|
value.forEach((item) => {
|
||||||
saveStatus(item, instance, {
|
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}
|
fetchItems={fetchHashtags}
|
||||||
checkForUpdates={checkForUpdates}
|
checkForUpdates={checkForUpdates}
|
||||||
useItemID
|
useItemID
|
||||||
view={media ? 'media' : undefined}
|
view={media || mediaFirst ? 'media' : undefined}
|
||||||
refresh={media}
|
refresh={media}
|
||||||
// allowFilters
|
// allowFilters
|
||||||
filterContext="public"
|
filterContext="public"
|
||||||
|
@ -233,23 +236,27 @@ function Hashtags({ media: mediaView, columnMode, ...props }) {
|
||||||
<MenuDivider />
|
<MenuDivider />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<MenuHeader className="plain">Filters</MenuHeader>
|
{!mediaFirst && (
|
||||||
<MenuItem
|
<>
|
||||||
type="checkbox"
|
<MenuHeader className="plain">Filters</MenuHeader>
|
||||||
checked={!!media}
|
<MenuItem
|
||||||
onClick={() => {
|
type="checkbox"
|
||||||
if (media) {
|
checked={!!media}
|
||||||
searchParams.delete('media');
|
onClick={() => {
|
||||||
} else {
|
if (media) {
|
||||||
searchParams.set('media', '1');
|
searchParams.delete('media');
|
||||||
}
|
} else {
|
||||||
setSearchParams(searchParams);
|
searchParams.set('media', '1');
|
||||||
}}
|
}
|
||||||
>
|
setSearchParams(searchParams);
|
||||||
<Icon icon="check-circle" />{' '}
|
}}
|
||||||
<span class="menu-grow">Media only</span>
|
>
|
||||||
</MenuItem>
|
<Icon icon="check-circle" />{' '}
|
||||||
<MenuDivider />
|
<span class="menu-grow">Media only</span>
|
||||||
|
</MenuItem>
|
||||||
|
<MenuDivider />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
<FocusableItem className="menu-field" disabled={reachLimit}>
|
<FocusableItem className="menu-field" disabled={reachLimit}>
|
||||||
{({ ref }) => (
|
{({ ref }) => (
|
||||||
<form
|
<form
|
||||||
|
|
Loading…
Add table
Reference in a new issue