style(topbar-edit-modal): match 4chan modal design and simplify subscription toggle

This commit is contained in:
plebeius
2025-11-07 22:10:06 +01:00
parent b886cbdf3b
commit d565d2ec87
2 changed files with 72 additions and 58 deletions
@@ -10,19 +10,21 @@
.topbarEditDialog { .topbarEditDialog {
position: absolute; position: absolute;
width: 600px; width: 400px;
max-height: 80vh; max-height: 80vh;
top: 50px; top: 50%;
left: 50%; left: 50%;
margin-left: -300px; margin-left: -200px;
transform: translateY(-50%);
padding: 2px;
background-color: var(--settings-modal-background-color); background-color: var(--settings-modal-background-color);
border-top: var(--settings-modal-border-top); border-top: var(--settings-modal-border-top);
border-right: var(--settings-modal-border-right); border-right: var(--settings-modal-border-right);
border-bottom: var(--settings-modal-border-bottom); border-bottom: var(--settings-modal-border-bottom);
border-left: var(--settings-modal-border-left); border-left: var(--settings-modal-border-left);
box-shadow: rgba(0, 0, 0, 0.1) 2px 2px 0px 1px; box-shadow: rgba(0, 0, 0, 0.25) 0px 0px 5px 0px;
font-size: var(--body-font-size); font-size: var(--body-font-size);
line-height: 16.003px; line-height: normal;
z-index: 1000; z-index: 1000;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -39,28 +41,29 @@
.hd { .hd {
position: relative; position: relative;
padding: 4px 6px; padding: 0px 0px 5px;
display: flex; margin: 5px 0px;
justify-content: space-between; text-align: center;
align-items: center;
border-bottom: var(--settings-modal-header-border-bottom); border-bottom: var(--settings-modal-header-border-bottom);
} }
.hd h2 { .hd h2 {
margin: 0; margin: 0;
padding: 0; padding: 0;
font-size: 131%; font-size: 16px;
font-weight: bold; font-weight: 700;
line-height: 14px;
height: 14px;
} }
.closeButton { .closeButton {
all: unset; all: unset;
cursor: pointer; cursor: pointer;
width: 16px; width: 18px;
height: 16px; height: 18px;
position: absolute; position: absolute;
top: 4px; top: -2px;
right: 4px; right: 3px;
background-image: var(--settings-modal-close-button-background-image); background-image: var(--settings-modal-close-button-background-image);
background-size: 100%; background-size: 100%;
background-position: center; background-position: center;
@@ -69,13 +72,14 @@
} }
.bd { .bd {
padding: 10px;
overflow-y: auto; overflow-y: auto;
flex: 1; flex: 1;
padding: 0;
margin: 0;
} }
.section { .section {
margin-bottom: 20px; margin-bottom: 0;
} }
.section:last-child { .section:last-child {
@@ -92,15 +96,20 @@
.directoryInput { .directoryInput {
width: 100%; width: 100%;
padding: 4px; padding: 2px 4px 3px;
font-size: var(--body-font-size); font-size: 13.3333px;
border: var(--reply-modal-field-input-border, 1px solid #aaa); margin: 0 0 5px;
box-sizing: border-box;
outline: none; outline: none;
font-family: var(--body-font-family, arial, helvetica, sans-serif); font-family: Arial, sans-serif;
border: var(--post-form-field-input-border, revert);
background-color: var(--post-form-field-input-background-color, revert);
color: var(--post-form-field-input-color);
} }
.directoryInput:focus { .directoryInput:focus {
border: var(--reply-modal-field-input-border-focus, 1px solid #ea8); outline: none;
border: var(--post-form-field-input-focus-border, revert);
} }
.checkboxGroup { .checkboxGroup {
@@ -114,6 +123,7 @@
display: flex; display: flex;
align-items: center; align-items: center;
gap: 4px; gap: 4px;
margin-bottom: 5px;
} }
.checkboxItem input[type='checkbox'] { .checkboxItem input[type='checkbox'] {
@@ -126,11 +136,20 @@
user-select: none; user-select: none;
} }
.topbarEditFooter { .editSubscriptionsLink {
padding: 10px; font-size: var(--body-font-size);
display: flex; color: var(--link-color, #0000ee);
justify-content: center; text-decoration: underline;
gap: 10px; cursor: pointer;
border-top: var(--settings-modal-header-border-bottom);
} }
.editSubscriptionsLink:hover {
color: var(--link-hover-color, #551a8b);
}
.topbarEditFooter {
padding: 0;
margin: 0;
text-align: center;
padding-bottom: 5px;
}
@@ -1,6 +1,6 @@
import { useEffect, useState, useMemo } from 'react'; import { useEffect, useState, useMemo } from 'react';
import { Link, useLocation } from 'react-router-dom';
import { useAccount } from '@plebbit/plebbit-react-hooks'; import { useAccount } from '@plebbit/plebbit-react-hooks';
import Plebbit from '@plebbit/plebbit-js';
import useTopbarEditModalStore from '../../stores/use-topbar-edit-modal-store'; import useTopbarEditModalStore from '../../stores/use-topbar-edit-modal-store';
import useTopbarVisibilityStore from '../../stores/use-topbar-visibility-store'; import useTopbarVisibilityStore from '../../stores/use-topbar-visibility-store';
import { getAllBoardCodes } from '../../constants/board-codes'; import { getAllBoardCodes } from '../../constants/board-codes';
@@ -11,6 +11,7 @@ const TopbarEditModal = () => {
const { visibleDirectories, visibleSubscriptions, setDirectoryVisibility, setSubscriptionVisibility } = useTopbarVisibilityStore(); const { visibleDirectories, visibleSubscriptions, setDirectoryVisibility, setSubscriptionVisibility } = useTopbarVisibilityStore();
const account = useAccount(); const account = useAccount();
const subscriptions = account?.subscriptions || []; const subscriptions = account?.subscriptions || [];
const location = useLocation();
// Convert visible directories set to space-separated string for input // Convert visible directories set to space-separated string for input
const directoriesToString = (dirs: Set<string>): string => { const directoriesToString = (dirs: Set<string>): string => {
@@ -36,16 +37,17 @@ const TopbarEditModal = () => {
// Local state for text input (will be saved on Save click) // Local state for text input (will be saved on Save click)
// Empty string means all directories visible (default), otherwise show only the specified codes // Empty string means all directories visible (default), otherwise show only the specified codes
const [localDirectoryInput, setLocalDirectoryInput] = useState<string>(allDirectoriesVisible ? '' : directoriesToString(visibleDirectories)); const [localDirectoryInput, setLocalDirectoryInput] = useState<string>(allDirectoriesVisible ? '' : directoriesToString(visibleDirectories));
const [localSubscriptionVisibility, setLocalSubscriptionVisibility] = useState<Set<string>>(visibleSubscriptions); // Check if all subscriptions are visible (if any subscription is visible, show subscriptions is checked)
const [showSubscriptions, setShowSubscriptions] = useState<boolean>(subscriptions.length > 0 && subscriptions.some((addr: string) => visibleSubscriptions.has(addr)));
// Update local state when modal opens or store changes // Update local state when modal opens or store changes
useEffect(() => { useEffect(() => {
if (showModal) { if (showModal) {
const allVisible = allBoardCodes.every((code) => visibleDirectories.has(code)); const allVisible = allBoardCodes.every((code) => visibleDirectories.has(code));
setLocalDirectoryInput(allVisible ? '' : directoriesToString(visibleDirectories)); setLocalDirectoryInput(allVisible ? '' : directoriesToString(visibleDirectories));
setLocalSubscriptionVisibility(new Set(visibleSubscriptions)); setShowSubscriptions(subscriptions.length > 0 && subscriptions.some((addr: string) => visibleSubscriptions.has(addr)));
} }
}, [showModal, visibleDirectories, visibleSubscriptions, allBoardCodes]); }, [showModal, visibleDirectories, visibleSubscriptions, allBoardCodes, subscriptions]);
if (!showModal) { if (!showModal) {
return null; return null;
@@ -57,16 +59,6 @@ const TopbarEditModal = () => {
} }
}; };
const handleSubscriptionToggle = (address: string) => {
const newSet = new Set(localSubscriptionVisibility);
if (newSet.has(address)) {
newSet.delete(address);
} else {
newSet.add(address);
}
setLocalSubscriptionVisibility(newSet);
};
const handleSave = () => { const handleSave = () => {
// If input is empty, show all directories (default behavior) // If input is empty, show all directories (default behavior)
// Otherwise, show only the directories specified in the input // Otherwise, show only the directories specified in the input
@@ -84,8 +76,10 @@ const TopbarEditModal = () => {
} }
// Apply subscription visibility changes // Apply subscription visibility changes
// If showSubscriptions is checked, make all subscriptions visible
// Otherwise, hide all subscriptions
subscriptions.forEach((address: string) => { subscriptions.forEach((address: string) => {
setSubscriptionVisibility(address, localSubscriptionVisibility.has(address)); setSubscriptionVisibility(address, showSubscriptions);
}); });
closeTopbarEditModal(); closeTopbarEditModal();
@@ -100,8 +94,6 @@ const TopbarEditModal = () => {
</div> </div>
<div className={styles.bd}> <div className={styles.bd}>
<div className={styles.section}> <div className={styles.section}>
<h3>Directory Boards</h3>
<p>Enter directory codes separated by spaces (e.g., "jp tg mu"):</p>
<input <input
type='text' type='text'
className={styles.directoryInput} className={styles.directoryInput}
@@ -113,19 +105,22 @@ const TopbarEditModal = () => {
{subscriptions.length > 0 && ( {subscriptions.length > 0 && (
<div className={styles.section}> <div className={styles.section}>
<h3>Subscriptions</h3> <div className={styles.checkboxItem}>
<p>Select which subscriptions to show in the topbar:</p> <input type='checkbox' id='show-subscriptions' checked={showSubscriptions} onChange={(e) => setShowSubscriptions(e.target.checked)} />
<div className={styles.checkboxGroup}> <label htmlFor='show-subscriptions'>
{subscriptions.map((address: string) => { show subscriptions (
const displayText = address.endsWith('.eth') || address.endsWith('.sol') ? address : Plebbit.getShortAddress(address); <Link
const isChecked = localSubscriptionVisibility.has(address); to={location.pathname.replace(/\/$/, '') + '/settings#subscriptions-settings'}
return ( className={styles.editSubscriptionsLink}
<div key={address} className={styles.checkboxItem}> onClick={(e) => {
<input type='checkbox' id={`subscription-${address}`} checked={isChecked} onChange={() => handleSubscriptionToggle(address)} /> e.stopPropagation();
<label htmlFor={`subscription-${address}`}>{displayText}</label> closeTopbarEditModal();
</div> }}
); >
})} edit subscriptions
</Link>
)
</label>
</div> </div>
</div> </div>
)} )}