mirror of
https://github.com/cheeaun/phanpy.git
synced 2025-02-24 16:58:47 +01:00
Add 'Full' view for status pages
This commit is contained in:
parent
39ec0d29e2
commit
9a04cb6ba3
4 changed files with 82 additions and 20 deletions
25
src/app.css
25
src/app.css
|
@ -826,6 +826,29 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
|
||||||
.deck-backdrop .deck .status {
|
.deck-backdrop .deck .status {
|
||||||
max-width: var(--main-width);
|
max-width: var(--main-width);
|
||||||
}
|
}
|
||||||
|
.deck-backdrop .deck.deck-view-full .menu-switch-view {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
@media (min-width: 40em) {
|
||||||
|
.deck-backdrop .deck.deck-view-full .menu-switch-view {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.deck-backdrop .deck.deck-view-full {
|
||||||
|
min-width: 100%;
|
||||||
|
background-image: radial-gradient(
|
||||||
|
circle,
|
||||||
|
transparent 30em,
|
||||||
|
var(--bg-faded-color)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
.deck-backdrop .deck.deck-view-full > * {
|
||||||
|
max-width: calc(var(--main-width) + 32px);
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.deck-backdrop .deck.deck-view-full .status {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.deck-close {
|
.deck-close {
|
||||||
color: var(--text-insignificant-color) !important;
|
color: var(--text-insignificant-color) !important;
|
||||||
|
@ -1096,7 +1119,7 @@ body:has(.media-modal-container + .status-deck) .media-post-link {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
flex-grow: 0;
|
flex-grow: 0;
|
||||||
}
|
}
|
||||||
.deck-backdrop .media-modal-container + .status-deck {
|
.deck-backdrop .media-modal-container + .status-deck:not(.deck-view-full) {
|
||||||
/* display: block; */
|
/* display: block; */
|
||||||
/* width: 350px; */
|
/* width: 350px; */
|
||||||
min-width: 350px;
|
min-width: 350px;
|
||||||
|
|
|
@ -77,6 +77,8 @@ const ICONS = {
|
||||||
filter: 'mingcute:filter-2-line',
|
filter: 'mingcute:filter-2-line',
|
||||||
chart: 'mingcute:chart-line-line',
|
chart: 'mingcute:chart-line-line',
|
||||||
react: 'mingcute:react-line',
|
react: 'mingcute:react-line',
|
||||||
|
layout4: 'mingcute:layout-4-line',
|
||||||
|
layout5: 'mingcute:layout-5-line',
|
||||||
};
|
};
|
||||||
|
|
||||||
const modules = import.meta.glob('/node_modules/@iconify-icons/mingcute/*.js');
|
const modules = import.meta.glob('/node_modules/@iconify-icons/mingcute/*.js');
|
||||||
|
|
|
@ -1037,7 +1037,7 @@ function Status({
|
||||||
onClick={
|
onClick={
|
||||||
onMediaClick
|
onMediaClick
|
||||||
? (e) => {
|
? (e) => {
|
||||||
onMediaClick(e, i, media);
|
onMediaClick(e, i, media, status);
|
||||||
}
|
}
|
||||||
: undefined
|
: undefined
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,13 @@ import './status.css';
|
||||||
import { Menu, MenuDivider, MenuHeader, MenuItem } from '@szhsin/react-menu';
|
import { Menu, MenuDivider, MenuHeader, MenuItem } from '@szhsin/react-menu';
|
||||||
import debounce from 'just-debounce-it';
|
import debounce from 'just-debounce-it';
|
||||||
import pRetry from 'p-retry';
|
import pRetry from 'p-retry';
|
||||||
import { useEffect, useMemo, useRef, useState } from 'preact/hooks';
|
import {
|
||||||
|
useCallback,
|
||||||
|
useEffect,
|
||||||
|
useMemo,
|
||||||
|
useRef,
|
||||||
|
useState,
|
||||||
|
} from 'preact/hooks';
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
import { InView } from 'react-intersection-observer';
|
import { InView } from 'react-intersection-observer';
|
||||||
import { matchPath, useParams, useSearchParams } from 'react-router-dom';
|
import { matchPath, useParams, useSearchParams } from 'react-router-dom';
|
||||||
|
@ -129,6 +135,7 @@ function StatusThread({ closeLink = '/' }) {
|
||||||
const [searchParams, setSearchParams] = useSearchParams();
|
const [searchParams, setSearchParams] = useSearchParams();
|
||||||
const mediaParam = searchParams.get('media');
|
const mediaParam = searchParams.get('media');
|
||||||
const showMedia = parseInt(mediaParam, 10) > 0;
|
const showMedia = parseInt(mediaParam, 10) > 0;
|
||||||
|
const [viewMode, setViewMode] = useState(searchParams.get('view'));
|
||||||
const { masto, instance } = api({ instance: params.instance });
|
const { masto, instance } = api({ instance: params.instance });
|
||||||
const {
|
const {
|
||||||
masto: currentMasto,
|
masto: currentMasto,
|
||||||
|
@ -545,13 +552,24 @@ function StatusThread({ closeLink = '/' }) {
|
||||||
|
|
||||||
const initialPageState = useRef(showMedia ? 'media+status' : 'status');
|
const initialPageState = useRef(showMedia ? 'media+status' : 'status');
|
||||||
|
|
||||||
|
const handleMediaClick = useCallback((e, i, media, status) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
setSearchParams({
|
||||||
|
media: i + 1,
|
||||||
|
mediaStatusID: status.id,
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
tabIndex="-1"
|
tabIndex="-1"
|
||||||
ref={scrollableRef}
|
ref={scrollableRef}
|
||||||
class={`status-deck deck contained ${
|
class={`status-deck deck contained ${
|
||||||
statuses.length > 1 ? 'padded-bottom' : ''
|
statuses.length > 1 ? 'padded-bottom' : ''
|
||||||
} ${initialPageState.current === 'status' ? 'slide-in' : ''}`}
|
} ${initialPageState.current === 'status' ? 'slide-in' : ''} ${
|
||||||
|
viewMode ? `deck-view-${viewMode}` : ''
|
||||||
|
}`}
|
||||||
>
|
>
|
||||||
<header
|
<header
|
||||||
class={`${heroInView ? 'inview' : ''} ${
|
class={`${heroInView ? 'inview' : ''} ${
|
||||||
|
@ -651,6 +669,30 @@ function StatusThread({ closeLink = '/' }) {
|
||||||
<Icon icon="refresh" />
|
<Icon icon="refresh" />
|
||||||
<span>Refresh</span>
|
<span>Refresh</span>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
<MenuItem
|
||||||
|
className="menu-switch-view"
|
||||||
|
onClick={() => {
|
||||||
|
setViewMode(viewMode === 'full' ? null : 'full');
|
||||||
|
if (viewMode === 'full') {
|
||||||
|
searchParams.delete('view');
|
||||||
|
} else {
|
||||||
|
searchParams.set('view', 'full');
|
||||||
|
}
|
||||||
|
setSearchParams(searchParams);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
icon={
|
||||||
|
{
|
||||||
|
'': 'layout5',
|
||||||
|
full: 'layout4',
|
||||||
|
}[viewMode || '']
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<span>
|
||||||
|
Switch to {viewMode === 'full' ? 'Side Peek' : 'Full'} view
|
||||||
|
</span>
|
||||||
|
</MenuItem>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
// Click all buttons with class .spoiler but not .spoiling
|
// Click all buttons with class .spoiler but not .spoiling
|
||||||
|
@ -802,14 +844,7 @@ function StatusThread({ closeLink = '/' }) {
|
||||||
withinContext
|
withinContext
|
||||||
size={thread || ancestor ? 'm' : 's'}
|
size={thread || ancestor ? 'm' : 's'}
|
||||||
enableTranslate
|
enableTranslate
|
||||||
onMediaClick={(e, i) => {
|
onMediaClick={handleMediaClick}
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
setSearchParams({
|
|
||||||
media: i + 1,
|
|
||||||
mediaStatusID: statusID,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
{ancestor && isThread && repliesCount > 1 && (
|
{ancestor && isThread && repliesCount > 1 && (
|
||||||
<div class="replies-link">
|
<div class="replies-link">
|
||||||
|
@ -962,6 +997,15 @@ function SubComments({
|
||||||
(!hasParentThread || replies.length === 1) && (isBrief || !hasManyStatuses);
|
(!hasParentThread || replies.length === 1) && (isBrief || !hasManyStatuses);
|
||||||
const openBefore = cachedRepliesToggle[replies[0].id];
|
const openBefore = cachedRepliesToggle[replies[0].id];
|
||||||
|
|
||||||
|
const handleMediaClick = useCallback((e, i, media, status) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
setSearchParams({
|
||||||
|
media: i + 1,
|
||||||
|
mediaStatusID: status.id,
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<details
|
<details
|
||||||
class="replies"
|
class="replies"
|
||||||
|
@ -1021,14 +1065,7 @@ function SubComments({
|
||||||
withinContext
|
withinContext
|
||||||
size="s"
|
size="s"
|
||||||
enableTranslate
|
enableTranslate
|
||||||
onMediaClick={(e, i) => {
|
onMediaClick={handleMediaClick}
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
setSearchParams({
|
|
||||||
media: i + 1,
|
|
||||||
mediaStatusID: r.id,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
{!r.replies?.length && r.repliesCount > 0 && (
|
{!r.replies?.length && r.repliesCount > 0 && (
|
||||||
<div class="replies-link">
|
<div class="replies-link">
|
||||||
|
|
Loading…
Reference in a new issue