Add 'Full' view for status pages

This commit is contained in:
Lim Chee Aun 2023-04-17 00:14:09 +08:00
parent 39ec0d29e2
commit 9a04cb6ba3
4 changed files with 82 additions and 20 deletions

View file

@ -826,6 +826,29 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
.deck-backdrop .deck .status {
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 {
color: var(--text-insignificant-color) !important;
@ -1096,7 +1119,7 @@ body:has(.media-modal-container + .status-deck) .media-post-link {
width: 100%;
flex-grow: 0;
}
.deck-backdrop .media-modal-container + .status-deck {
.deck-backdrop .media-modal-container + .status-deck:not(.deck-view-full) {
/* display: block; */
/* width: 350px; */
min-width: 350px;

View file

@ -77,6 +77,8 @@ const ICONS = {
filter: 'mingcute:filter-2-line',
chart: 'mingcute:chart-line-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');

View file

@ -1037,7 +1037,7 @@ function Status({
onClick={
onMediaClick
? (e) => {
onMediaClick(e, i, media);
onMediaClick(e, i, media, status);
}
: undefined
}

View file

@ -3,7 +3,13 @@ import './status.css';
import { Menu, MenuDivider, MenuHeader, MenuItem } from '@szhsin/react-menu';
import debounce from 'just-debounce-it';
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 { InView } from 'react-intersection-observer';
import { matchPath, useParams, useSearchParams } from 'react-router-dom';
@ -129,6 +135,7 @@ function StatusThread({ closeLink = '/' }) {
const [searchParams, setSearchParams] = useSearchParams();
const mediaParam = searchParams.get('media');
const showMedia = parseInt(mediaParam, 10) > 0;
const [viewMode, setViewMode] = useState(searchParams.get('view'));
const { masto, instance } = api({ instance: params.instance });
const {
masto: currentMasto,
@ -545,13 +552,24 @@ function StatusThread({ closeLink = '/' }) {
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 (
<div
tabIndex="-1"
ref={scrollableRef}
class={`status-deck deck contained ${
statuses.length > 1 ? 'padded-bottom' : ''
} ${initialPageState.current === 'status' ? 'slide-in' : ''}`}
} ${initialPageState.current === 'status' ? 'slide-in' : ''} ${
viewMode ? `deck-view-${viewMode}` : ''
}`}
>
<header
class={`${heroInView ? 'inview' : ''} ${
@ -651,6 +669,30 @@ function StatusThread({ closeLink = '/' }) {
<Icon icon="refresh" />
<span>Refresh</span>
</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
onClick={() => {
// Click all buttons with class .spoiler but not .spoiling
@ -802,14 +844,7 @@ function StatusThread({ closeLink = '/' }) {
withinContext
size={thread || ancestor ? 'm' : 's'}
enableTranslate
onMediaClick={(e, i) => {
e.preventDefault();
e.stopPropagation();
setSearchParams({
media: i + 1,
mediaStatusID: statusID,
});
}}
onMediaClick={handleMediaClick}
/>
{ancestor && isThread && repliesCount > 1 && (
<div class="replies-link">
@ -962,6 +997,15 @@ function SubComments({
(!hasParentThread || replies.length === 1) && (isBrief || !hasManyStatuses);
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 (
<details
class="replies"
@ -1021,14 +1065,7 @@ function SubComments({
withinContext
size="s"
enableTranslate
onMediaClick={(e, i) => {
e.preventDefault();
e.stopPropagation();
setSearchParams({
media: i + 1,
mediaStatusID: r.id,
});
}}
onMediaClick={handleMediaClick}
/>
{!r.replies?.length && r.repliesCount > 0 && (
<div class="replies-link">