mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
style(mod queue): adjust mobile design
This commit is contained in:
@@ -72,7 +72,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.numberHeader {
|
.numberHeader {
|
||||||
width: 60px;
|
min-width: 60px;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,7 +175,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.number {
|
.number {
|
||||||
width: 60px;
|
min-width: 60px;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,6 +210,10 @@
|
|||||||
animation: blink 2s infinite;
|
animation: blink 2s infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.alertWrapper {
|
||||||
|
/* Container for the time ago indicator with parentheses, hidden on mobile */
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes blink {
|
@keyframes blink {
|
||||||
0% { opacity: 1; }
|
0% { opacity: 1; }
|
||||||
50% { opacity: 0.5; }
|
50% { opacity: 0.5; }
|
||||||
@@ -225,6 +229,10 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.actionButtons {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
/* Desktop: buttons styled as text links (same as board buttons) */
|
/* Desktop: buttons styled as text links (same as board buttons) */
|
||||||
@media (min-width: 640px) {
|
@media (min-width: 640px) {
|
||||||
.actions {
|
.actions {
|
||||||
@@ -304,53 +312,10 @@ span.reject:hover {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mobile Layout */
|
/* Mobile Layout - keeps table structure like desktop, just narrower columns */
|
||||||
@media (max-width: 600px) {
|
@media (max-width: 600px) {
|
||||||
.tableHeader {
|
.container {
|
||||||
display: none;
|
padding: 5px;
|
||||||
}
|
|
||||||
|
|
||||||
.row {
|
|
||||||
flex-wrap: wrap;
|
|
||||||
padding: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.time {
|
|
||||||
margin-left: auto;
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.excerpt {
|
|
||||||
width: 100%;
|
|
||||||
margin: 4px 0;
|
|
||||||
white-space: normal;
|
|
||||||
display: -webkit-box;
|
|
||||||
-webkit-line-clamp: 2;
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
}
|
|
||||||
|
|
||||||
.actions {
|
|
||||||
width: 100%;
|
|
||||||
justify-content: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button {
|
|
||||||
flex: 1;
|
|
||||||
text-align: center;
|
|
||||||
padding: 8px;
|
|
||||||
border: var(--button-border-mobile);
|
|
||||||
background: var(--button-background-color-mobile);
|
|
||||||
color: var(--button-text-color-mobile);
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button:hover {
|
|
||||||
background: var(--button-background-color-mobile);
|
|
||||||
}
|
|
||||||
|
|
||||||
.button:disabled {
|
|
||||||
opacity: 0.5;
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
@@ -361,4 +326,117 @@ span.reject:hover {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tableHeader {
|
||||||
|
font-size: 8pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
.numberHeader {
|
||||||
|
min-width: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeHeader {
|
||||||
|
width: 90px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actionsHeader {
|
||||||
|
width: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
font-size: 8pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove background colors for rows on mobile */
|
||||||
|
:global(body.yotsuba) .rowOdd .number,
|
||||||
|
:global(body.yotsuba) .rowOdd .excerpt,
|
||||||
|
:global(body.yotsuba) .rowOdd .time,
|
||||||
|
:global(body.yotsuba) .rowOdd .actions,
|
||||||
|
:global(body.yotsuba-b) .rowOdd .number,
|
||||||
|
:global(body.yotsuba-b) .rowOdd .excerpt,
|
||||||
|
:global(body.yotsuba-b) .rowOdd .time,
|
||||||
|
:global(body.yotsuba-b) .rowOdd .actions,
|
||||||
|
:global(body.futaba) .rowOdd .number,
|
||||||
|
:global(body.futaba) .rowOdd .excerpt,
|
||||||
|
:global(body.futaba) .rowOdd .time,
|
||||||
|
:global(body.futaba) .rowOdd .actions,
|
||||||
|
:global(body.burichan) .rowOdd .number,
|
||||||
|
:global(body.burichan) .rowOdd .excerpt,
|
||||||
|
:global(body.burichan) .rowOdd .time,
|
||||||
|
:global(body.burichan) .rowOdd .actions,
|
||||||
|
:global(body.tomorrow) .rowOdd .number,
|
||||||
|
:global(body.tomorrow) .rowOdd .excerpt,
|
||||||
|
:global(body.tomorrow) .rowOdd .time,
|
||||||
|
:global(body.tomorrow) .rowOdd .actions,
|
||||||
|
:global(body.photon) .rowOdd .number,
|
||||||
|
:global(body.photon) .rowOdd .excerpt,
|
||||||
|
:global(body.photon) .rowOdd .time,
|
||||||
|
:global(body.photon) .rowOdd .actions {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.number {
|
||||||
|
min-width: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.excerpt {
|
||||||
|
white-space: normal;
|
||||||
|
overflow: visible;
|
||||||
|
text-overflow: clip;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time {
|
||||||
|
width: 90px;
|
||||||
|
white-space: normal;
|
||||||
|
overflow: visible;
|
||||||
|
text-overflow: clip;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hide the time ago indicator (including parentheses) on mobile to save space */
|
||||||
|
.alertWrapper {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions {
|
||||||
|
width: 80px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-end;
|
||||||
|
gap: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actionButtons {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-end;
|
||||||
|
gap: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.buttonWrapper {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Keep desktop-style text buttons on mobile */
|
||||||
|
.button {
|
||||||
|
all: unset;
|
||||||
|
cursor: pointer;
|
||||||
|
text-transform: capitalize;
|
||||||
|
color: var(--button-desktop-text-color);
|
||||||
|
text-decoration: var(--button-text-decoration);
|
||||||
|
display: inline;
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: 8pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:hover {
|
||||||
|
color: var(--button-desktop-text-color-hover);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:disabled {
|
||||||
|
opacity: 0.5;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import useFeedResetStore from '../../stores/use-feed-reset-store';
|
|||||||
import useChallengesStore from '../../stores/use-challenges-store';
|
import useChallengesStore from '../../stores/use-challenges-store';
|
||||||
import { alertChallengeVerificationFailed } from '../../lib/utils/challenge-utils';
|
import { alertChallengeVerificationFailed } from '../../lib/utils/challenge-utils';
|
||||||
import Tooltip from '../../components/tooltip';
|
import Tooltip from '../../components/tooltip';
|
||||||
|
import useIsMobile from '../../hooks/use-is-mobile';
|
||||||
|
|
||||||
const { addChallenge } = useChallengesStore.getState();
|
const { addChallenge } = useChallengesStore.getState();
|
||||||
|
|
||||||
@@ -58,6 +59,7 @@ const ModQueueRow = ({ comment, isOdd = false }: ModQueueRowProps) => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { getAlertThresholdSeconds } = useModQueueStore();
|
const { getAlertThresholdSeconds } = useModQueueStore();
|
||||||
const [initiatedAction, setInitiatedAction] = useState<ModerationAction>(null);
|
const [initiatedAction, setInitiatedAction] = useState<ModerationAction>(null);
|
||||||
|
const isMobile = useIsMobile();
|
||||||
|
|
||||||
const { editedComment } = useEditedComment({ comment });
|
const { editedComment } = useEditedComment({ comment });
|
||||||
const displayComment = editedComment || comment;
|
const displayComment = editedComment || comment;
|
||||||
@@ -154,7 +156,8 @@ const ModQueueRow = ({ comment, isOdd = false }: ModQueueRowProps) => {
|
|||||||
(hasLink ? link : null) ||
|
(hasLink ? link : null) ||
|
||||||
(getHasThumbnail(getCommentMediaInfo(link, thumbnailUrl, linkWidth, linkHeight), link) ? t('image') : null) ||
|
(getHasThumbnail(getCommentMediaInfo(link, thumbnailUrl, linkWidth, linkHeight), link) ? t('image') : null) ||
|
||||||
t('no_content');
|
t('no_content');
|
||||||
const excerpt = rawExcerpt.length > 101 ? rawExcerpt.slice(0, 98) + '...' : rawExcerpt;
|
// Only truncate excerpt on desktop, allow wrapping on mobile
|
||||||
|
const excerpt = !isMobile && rawExcerpt.length > 101 ? rawExcerpt.slice(0, 98) + '...' : rawExcerpt;
|
||||||
const threadTargetCid = threadCid || cid;
|
const threadTargetCid = threadCid || cid;
|
||||||
const postUrl = boardPath && threadTargetCid ? `/${boardPath}/thread/${threadTargetCid}` : undefined;
|
const postUrl = boardPath && threadTargetCid ? `/${boardPath}/thread/${threadTargetCid}` : undefined;
|
||||||
|
|
||||||
@@ -186,17 +189,22 @@ const ModQueueRow = ({ comment, isOdd = false }: ModQueueRowProps) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div className={styles.actionButtons}>
|
||||||
[
|
<span className={styles.buttonWrapper}>
|
||||||
<button className={styles.button} onClick={handleApprove} disabled={isPublishing}>
|
[
|
||||||
{t('approve')}
|
<button className={styles.button} onClick={handleApprove} disabled={isPublishing}>
|
||||||
</button>
|
{t('approve')}
|
||||||
] [
|
</button>
|
||||||
<button className={styles.button} onClick={handleReject} disabled={isPublishing}>
|
]
|
||||||
{t('reject')}
|
</span>
|
||||||
</button>
|
<span className={styles.buttonWrapper}>
|
||||||
]
|
[
|
||||||
</>
|
<button className={styles.button} onClick={handleReject} disabled={isPublishing}>
|
||||||
|
{t('reject')}
|
||||||
|
</button>
|
||||||
|
]
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -213,10 +221,27 @@ const ModQueueRow = ({ comment, isOdd = false }: ModQueueRowProps) => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.time}>
|
<div className={styles.time}>
|
||||||
{isAwaitingApproval && isOverThreshold ? (
|
{isMobile ? (
|
||||||
|
// On mobile, show shorter time ago format without tooltip
|
||||||
|
isAwaitingApproval && isOverThreshold ? (
|
||||||
|
<>
|
||||||
|
<span>{getFormattedTimeAgo(timestamp)}</span>
|
||||||
|
<span className={styles.alertWrapper}>
|
||||||
|
{' '}
|
||||||
|
(<span className={styles.alert}>{getFormattedTimeAgo(timestamp)}</span>)
|
||||||
|
</span>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<span>{getFormattedTimeAgo(timestamp)}</span>
|
||||||
|
)
|
||||||
|
) : // On desktop, show full date with tooltip
|
||||||
|
isAwaitingApproval && isOverThreshold ? (
|
||||||
<>
|
<>
|
||||||
<Tooltip children={<span>{getFormattedDate(timestamp)}</span>} content={getFormattedTimeAgo(timestamp)} /> (
|
<Tooltip children={<span>{getFormattedDate(timestamp)}</span>} content={getFormattedTimeAgo(timestamp)} />
|
||||||
<span className={styles.alert}>{getFormattedTimeAgo(timestamp)}</span>)
|
<span className={styles.alertWrapper}>
|
||||||
|
{' '}
|
||||||
|
(<span className={styles.alert}>{getFormattedTimeAgo(timestamp)}</span>)
|
||||||
|
</span>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<Tooltip children={<span>{getFormattedDate(timestamp)}</span>} content={getFormattedTimeAgo(timestamp)} />
|
<Tooltip children={<span>{getFormattedDate(timestamp)}</span>} content={getFormattedTimeAgo(timestamp)} />
|
||||||
|
|||||||
Reference in New Issue
Block a user