mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
feat(topbar): add customizable visibility controls for directories and subscriptions
This commit is contained in:
@@ -4,19 +4,23 @@
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(128, 128, 128, 0.5);
|
||||
background-color: rgba(0, 0, 0, 0.25);
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.backdropHome {
|
||||
background-color: rgba(128, 128, 128, 0.5);
|
||||
}
|
||||
|
||||
.directoryDialog {
|
||||
position: absolute;
|
||||
width: 500px;
|
||||
top: 50px;
|
||||
left: 50%;
|
||||
margin-left: -251px;
|
||||
background-color: rgb(255, 255, 255);
|
||||
border: 1px solid rgb(136, 0, 0);
|
||||
color: rgb(136, 0, 0);
|
||||
background-color: var(--directory-modal-background-color, #f0e0d6);
|
||||
border: var(--directory-modal-border, 1px solid #d9bfb7);
|
||||
color: var(--directory-modal-text-color, #800);
|
||||
box-shadow: rgba(0, 0, 0, 0.1) 2px 2px 0px 1px;
|
||||
font-family: arial, helvetica, clean, sans-serif;
|
||||
font-size: 13px;
|
||||
@@ -35,8 +39,8 @@
|
||||
|
||||
.hd {
|
||||
position: relative;
|
||||
background-color: rgb(136, 0, 0);
|
||||
color: rgb(255, 255, 255);
|
||||
background-color: var(--directory-modal-header-background-color, #ea8);
|
||||
color: var(--directory-modal-header-text-color, #800);
|
||||
padding: 4px 6px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
@@ -58,7 +62,7 @@
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
right: 4px;
|
||||
background-image: var(--disclaimer-modal-close-button-background-image);
|
||||
background-image: var(--directory-modal-close-button-background-image, url("/assets/buttons/cross-red.png"));
|
||||
background-size: 100%;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
@@ -91,7 +95,7 @@
|
||||
padding: 0;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
color: rgb(136, 0, 0);
|
||||
color: var(--directory-modal-text-color, #800);
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
|
||||
@@ -106,7 +110,7 @@
|
||||
}
|
||||
|
||||
.bd a {
|
||||
color: rgb(136, 0, 0);
|
||||
color: var(--directory-modal-text-color, #800);
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import useDirectoryModalStore from '../../stores/use-directory-modal-store';
|
||||
import styles from './directory-modal.module.css';
|
||||
|
||||
const DirectoryModal = () => {
|
||||
const { showModal, closeDirectoryModal } = useDirectoryModalStore();
|
||||
const location = useLocation();
|
||||
const isHomeView = location.pathname === '/';
|
||||
|
||||
if (!showModal) {
|
||||
return null;
|
||||
@@ -15,7 +18,7 @@ const DirectoryModal = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.backdrop} onClick={handleBackdropClick}>
|
||||
<div className={`${styles.backdrop} ${isHomeView ? styles.backdropHome : ''}`} onClick={handleBackdropClick}>
|
||||
<div className={styles.directoryDialog}>
|
||||
<div className={styles.hd}>
|
||||
<h2>Submit a Board to a Directory</h2>
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
top: 50px;
|
||||
left: 50%;
|
||||
margin-left: -151px;
|
||||
background-color: rgb(255, 255, 255);
|
||||
border: 1px solid rgb(136, 0, 0);
|
||||
color: rgb(136, 0, 0);
|
||||
background-color: var(--disclaimer-modal-background-color, rgb(255, 255, 255));
|
||||
border: var(--disclaimer-modal-border, 1px solid rgb(136, 0, 0));
|
||||
color: var(--disclaimer-modal-text-color, rgb(136, 0, 0));
|
||||
box-shadow: rgba(0, 0, 0, 0.1) 2px 2px 0px 1px;
|
||||
font-family: arial, helvetica, clean, sans-serif;
|
||||
font-size: 13px;
|
||||
@@ -26,8 +26,8 @@
|
||||
|
||||
.hd {
|
||||
position: relative;
|
||||
background-color: rgb(136, 0, 0);
|
||||
color: rgb(255, 255, 255);
|
||||
background-color: var(--disclaimer-modal-header-background-color, rgb(136, 0, 0));
|
||||
color: var(--disclaimer-modal-header-text-color, rgb(255, 255, 255));
|
||||
padding: 4px 6px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
@@ -70,7 +70,7 @@
|
||||
}
|
||||
|
||||
.bd a {
|
||||
color: rgb(136, 0, 0);
|
||||
color: var(--disclaimer-modal-text-color, rgb(136, 0, 0));
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import useDisclaimerModalStore from '../../stores/use-disclaimer-modal-store';
|
||||
import useDirectoryModalStore from '../../stores/use-directory-modal-store';
|
||||
import styles from './disclaimer-modal.module.css';
|
||||
|
||||
const DisclaimerModal = () => {
|
||||
const navigate = useNavigate();
|
||||
const { showModal, closeDisclaimerModal, acceptDisclaimer } = useDisclaimerModalStore();
|
||||
const { showModal, closeDisclaimerModal, acceptDisclaimer, targetBoardPath } = useDisclaimerModalStore();
|
||||
const { openDirectoryModal } = useDirectoryModalStore();
|
||||
|
||||
if (!showModal) {
|
||||
return null;
|
||||
@@ -17,7 +19,13 @@ const DisclaimerModal = () => {
|
||||
};
|
||||
|
||||
const handleAccept = () => {
|
||||
acceptDisclaimer(navigate);
|
||||
// If there's no board path (placeholder), show directory modal instead
|
||||
if (!targetBoardPath) {
|
||||
closeDisclaimerModal();
|
||||
openDirectoryModal();
|
||||
} else {
|
||||
acceptDisclaimer(navigate);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from './topbar-edit-modal';
|
||||
@@ -0,0 +1,142 @@
|
||||
.backdrop {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.25);
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.topbarEditDialog {
|
||||
position: absolute;
|
||||
width: 600px;
|
||||
max-height: 80vh;
|
||||
top: 50px;
|
||||
left: 50%;
|
||||
margin-left: -300px;
|
||||
background-color: var(--settings-modal-background-color);
|
||||
border-top: var(--settings-modal-border-top);
|
||||
border-right: var(--settings-modal-border-right);
|
||||
border-bottom: var(--settings-modal-border-bottom);
|
||||
border-left: var(--settings-modal-border-left);
|
||||
box-shadow: rgba(0, 0, 0, 0.1) 2px 2px 0px 1px;
|
||||
font-size: var(--body-font-size);
|
||||
line-height: 16.003px;
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.topbarEditDialog {
|
||||
width: calc(100% - 20px);
|
||||
margin-left: -50%;
|
||||
left: 50%;
|
||||
max-width: 600px;
|
||||
}
|
||||
}
|
||||
|
||||
.hd {
|
||||
position: relative;
|
||||
padding: 4px 6px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-bottom: var(--settings-modal-header-border-bottom);
|
||||
}
|
||||
|
||||
.hd h2 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 131%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.closeButton {
|
||||
all: unset;
|
||||
cursor: pointer;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
right: 4px;
|
||||
background-image: var(--settings-modal-close-button-background-image);
|
||||
background-size: 100%;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
|
||||
.bd {
|
||||
padding: 10px;
|
||||
overflow-y: auto;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.section {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.section:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.section h3 {
|
||||
margin: 0 0 8px 0;
|
||||
padding: 0;
|
||||
font-size: calc(var(--body-font-size) * 1.077);
|
||||
font-weight: bold;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
|
||||
.directoryInput {
|
||||
width: 100%;
|
||||
padding: 4px;
|
||||
font-size: var(--body-font-size);
|
||||
border: var(--reply-modal-field-input-border, 1px solid #aaa);
|
||||
outline: none;
|
||||
font-family: var(--body-font-family, arial, helvetica, sans-serif);
|
||||
}
|
||||
|
||||
.directoryInput:focus {
|
||||
border: var(--reply-modal-field-input-border-focus, 1px solid #ea8);
|
||||
}
|
||||
|
||||
.checkboxGroup {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.checkboxItem {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.checkboxItem input[type='checkbox'] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.checkboxItem label {
|
||||
cursor: pointer;
|
||||
font-size: var(--body-font-size);
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.topbarEditFooter {
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
border-top: var(--settings-modal-header-border-bottom);
|
||||
}
|
||||
|
||||
.topbarEditFooter button {
|
||||
padding: 4px 12px;
|
||||
cursor: pointer;
|
||||
font-size: var(--body-font-size);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useAccount } from '@plebbit/plebbit-react-hooks';
|
||||
import Plebbit from '@plebbit/plebbit-js';
|
||||
import useTopbarEditModalStore from '../../stores/use-topbar-edit-modal-store';
|
||||
import useTopbarVisibilityStore from '../../stores/use-topbar-visibility-store';
|
||||
import { getAllBoardCodes } from '../../constants/board-codes';
|
||||
import { getBoardPath } from '../../lib/utils/route-utils';
|
||||
import { useDefaultSubplebbits } from '../../hooks/use-default-subplebbits';
|
||||
import styles from './topbar-edit-modal.module.css';
|
||||
|
||||
const TopbarEditModal = () => {
|
||||
const { showModal, closeTopbarEditModal } = useTopbarEditModalStore();
|
||||
const { visibleDirectories, visibleSubscriptions, setDirectoryVisibility, setSubscriptionVisibility } = useTopbarVisibilityStore();
|
||||
const account = useAccount();
|
||||
const subscriptions = account?.subscriptions || [];
|
||||
const defaultSubplebbits = useDefaultSubplebbits();
|
||||
|
||||
// Convert visible directories set to space-separated string for input
|
||||
const directoriesToString = (dirs: Set<string>): string => {
|
||||
return Array.from(dirs).sort().join(' ');
|
||||
};
|
||||
|
||||
// Convert space-separated string to set of directory codes
|
||||
const stringToDirectories = (str: string): Set<string> => {
|
||||
const codes = str
|
||||
.trim()
|
||||
.split(/\s+/)
|
||||
.filter((code) => code.length > 0)
|
||||
.map((code) => code.toLowerCase());
|
||||
return new Set(codes);
|
||||
};
|
||||
|
||||
// Local state for text input (will be saved on Save click)
|
||||
const [localDirectoryInput, setLocalDirectoryInput] = useState<string>(directoriesToString(visibleDirectories));
|
||||
const [localSubscriptionVisibility, setLocalSubscriptionVisibility] = useState<Set<string>>(visibleSubscriptions);
|
||||
|
||||
// Update local state when modal opens or store changes
|
||||
useEffect(() => {
|
||||
if (showModal) {
|
||||
setLocalDirectoryInput(directoriesToString(visibleDirectories));
|
||||
setLocalSubscriptionVisibility(new Set(visibleSubscriptions));
|
||||
}
|
||||
}, [showModal, visibleDirectories, visibleSubscriptions]);
|
||||
|
||||
if (!showModal) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const handleBackdropClick = (e: React.MouseEvent<HTMLDivElement>) => {
|
||||
if (e.target === e.currentTarget) {
|
||||
closeTopbarEditModal();
|
||||
}
|
||||
};
|
||||
|
||||
const handleSubscriptionToggle = (address: string) => {
|
||||
const newSet = new Set(localSubscriptionVisibility);
|
||||
if (newSet.has(address)) {
|
||||
newSet.delete(address);
|
||||
} else {
|
||||
newSet.add(address);
|
||||
}
|
||||
setLocalSubscriptionVisibility(newSet);
|
||||
};
|
||||
|
||||
const handleSave = () => {
|
||||
// Parse directory input and apply changes
|
||||
const inputDirectories = stringToDirectories(localDirectoryInput);
|
||||
const allCodes = getAllBoardCodes();
|
||||
|
||||
// Hide all directories first, then show only the ones in the input
|
||||
allCodes.forEach((code) => {
|
||||
setDirectoryVisibility(code, inputDirectories.has(code));
|
||||
});
|
||||
|
||||
// Apply subscription visibility changes
|
||||
subscriptions.forEach((address: string) => {
|
||||
setSubscriptionVisibility(address, localSubscriptionVisibility.has(address));
|
||||
});
|
||||
|
||||
closeTopbarEditModal();
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
// Reset local state to match store
|
||||
setLocalDirectoryInput(directoriesToString(visibleDirectories));
|
||||
setLocalSubscriptionVisibility(new Set(visibleSubscriptions));
|
||||
closeTopbarEditModal();
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.backdrop} onClick={handleBackdropClick}>
|
||||
<div className={styles.topbarEditDialog}>
|
||||
<div className={styles.hd}>
|
||||
<h2>Custom Board List</h2>
|
||||
<button className={styles.closeButton} onClick={handleCancel} title='Close' />
|
||||
</div>
|
||||
<div className={styles.bd}>
|
||||
<div className={styles.section}>
|
||||
<h3>Directory Boards</h3>
|
||||
<p>Enter directory codes separated by spaces (e.g., "jp tg mu"):</p>
|
||||
<input
|
||||
type='text'
|
||||
className={styles.directoryInput}
|
||||
placeholder='Example: jp tg mu'
|
||||
value={localDirectoryInput}
|
||||
onChange={(e) => setLocalDirectoryInput(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{subscriptions.length > 0 && (
|
||||
<div className={styles.section}>
|
||||
<h3>Subscriptions</h3>
|
||||
<p>Select which subscriptions to show in the topbar:</p>
|
||||
<div className={styles.checkboxGroup}>
|
||||
{subscriptions.map((address: string) => {
|
||||
const boardPath = getBoardPath(address, defaultSubplebbits);
|
||||
const displayText = address.endsWith('.eth') || address.endsWith('.sol') ? address : Plebbit.getShortAddress(address);
|
||||
const isChecked = localSubscriptionVisibility.has(address);
|
||||
return (
|
||||
<div key={address} className={styles.checkboxItem}>
|
||||
<input type='checkbox' id={`subscription-${address}`} checked={isChecked} onChange={() => handleSubscriptionToggle(address)} />
|
||||
<label htmlFor={`subscription-${address}`}>{boardPath || displayText}</label>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className={styles.topbarEditFooter}>
|
||||
<button onClick={handleSave}>Save</button>
|
||||
<button onClick={handleCancel}>Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default TopbarEditModal;
|
||||
@@ -0,0 +1,13 @@
|
||||
// Types for topbar edit modal component
|
||||
|
||||
export interface BoardCodeCheckbox {
|
||||
code: string;
|
||||
label: string;
|
||||
checked: boolean;
|
||||
}
|
||||
|
||||
export interface SubscriptionCheckbox {
|
||||
address: string;
|
||||
displayName: string;
|
||||
checked: boolean;
|
||||
}
|
||||
@@ -22,6 +22,11 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
text-decoration: line-through;
|
||||
color: var(--topbar-desktop-link-text-color);
|
||||
}
|
||||
|
||||
.navTopRight {
|
||||
float: right;
|
||||
text-transform: capitalize;
|
||||
|
||||
@@ -4,11 +4,15 @@ import { useTranslation } from 'react-i18next';
|
||||
import Plebbit from '@plebbit/plebbit-js';
|
||||
import { useAccount, useAccountComment, useAccountSubplebbits } from '@plebbit/plebbit-react-hooks';
|
||||
import { isAllView, isCatalogView, isSubscriptionsView } from '../../lib/utils/view-utils';
|
||||
import { useDefaultSubplebbitAddresses, useDefaultSubplebbits } from '../../hooks/use-default-subplebbits';
|
||||
import { useDefaultSubplebbitAddresses, useDefaultSubplebbits, MultisubSubplebbit } from '../../hooks/use-default-subplebbits';
|
||||
import { useBoardPath, useResolvedSubplebbitAddress } from '../../hooks/use-resolved-subplebbit-address';
|
||||
import { getBoardPath } from '../../lib/utils/route-utils';
|
||||
import { getBoardPath, extractDirectoryFromTitle } from '../../lib/utils/route-utils';
|
||||
import { TimeFilter } from '../board-buttons';
|
||||
import useCreateBoardModalStore from '../../stores/use-create-board-modal-store';
|
||||
import useTopbarEditModalStore from '../../stores/use-topbar-edit-modal-store';
|
||||
import useTopbarVisibilityStore from '../../stores/use-topbar-visibility-store';
|
||||
import useDirectoryModalStore from '../../stores/use-directory-modal-store';
|
||||
import { BOARD_CODE_GROUPS } from '../../constants/board-codes';
|
||||
import styles from './topbar.module.css';
|
||||
import _, { debounce } from 'lodash';
|
||||
|
||||
@@ -71,6 +75,16 @@ const SearchBar = ({ setShowSearchBar }: { setShowSearchBar: (show: boolean) =>
|
||||
);
|
||||
};
|
||||
|
||||
// Helper function to find board address by directory code
|
||||
const findBoardAddressByCode = (code: string, defaultSubplebbits: MultisubSubplebbit[]): string | null => {
|
||||
const entry = defaultSubplebbits.find((subplebbit) => {
|
||||
if (!subplebbit.title) return false;
|
||||
const directory = extractDirectoryFromTitle(subplebbit.title);
|
||||
return directory === code;
|
||||
});
|
||||
return entry?.address || null;
|
||||
};
|
||||
|
||||
const TopBarDesktop = () => {
|
||||
const { t } = useTranslation();
|
||||
const account = useAccount();
|
||||
@@ -79,13 +93,72 @@ const TopBarDesktop = () => {
|
||||
const isInCatalogView = isCatalogView(location.pathname, params);
|
||||
const [showSearchBar, setShowSearchBar] = useState(false);
|
||||
const { openCreateBoardModal } = useCreateBoardModalStore();
|
||||
const { openTopbarEditModal } = useTopbarEditModalStore();
|
||||
const { openDirectoryModal } = useDirectoryModalStore();
|
||||
const { visibleDirectories, visibleSubscriptions } = useTopbarVisibilityStore();
|
||||
const defaultSubplebbits = useDefaultSubplebbits();
|
||||
|
||||
const subscriptions = account?.subscriptions;
|
||||
|
||||
const subscriptions = account?.subscriptions || [];
|
||||
const { accountSubplebbits } = useAccountSubplebbits();
|
||||
const accountSubplebbitAddresses = Object.keys(accountSubplebbits);
|
||||
|
||||
// Filter subscriptions to only show visible ones
|
||||
const visibleSubscriptionAddresses = subscriptions.filter((address: string) => visibleSubscriptions.has(address));
|
||||
|
||||
// Initialize visibility store on mount
|
||||
useEffect(() => {
|
||||
useTopbarVisibilityStore.getState().initialize();
|
||||
}, []);
|
||||
|
||||
// Render a board code link or placeholder
|
||||
const renderBoardCode = (code: string, isLastInGroup: boolean) => {
|
||||
const address = findBoardAddressByCode(code, defaultSubplebbits);
|
||||
const isPlaceholder = !address;
|
||||
|
||||
const handleClick = (e: React.MouseEvent) => {
|
||||
// If no address exists, prevent navigation and open directory modal
|
||||
if (!address) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
openDirectoryModal();
|
||||
}
|
||||
};
|
||||
|
||||
const linkContent = (
|
||||
<>
|
||||
{isPlaceholder ? (
|
||||
<span className={styles.placeholder} onClick={handleClick} style={{ cursor: 'pointer' }}>
|
||||
{code}
|
||||
</span>
|
||||
) : (
|
||||
<Link to={`/${code}${isInCatalogView ? '/catalog' : ''}`} onClick={handleClick}>
|
||||
{code}
|
||||
</Link>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
||||
return (
|
||||
<span key={code}>
|
||||
{linkContent}
|
||||
{!isLastInGroup && ' / '}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
// Render a subscription link
|
||||
const renderSubscription = (address: string, index: number, total: number) => {
|
||||
const boardPath = getBoardPath(address, defaultSubplebbits);
|
||||
const displayText = address.endsWith('.eth') || address.endsWith('.sol') ? address : Plebbit.getShortAddress(address);
|
||||
|
||||
return (
|
||||
<span key={address}>
|
||||
{boardPath && boardPath.trim() ? <Link to={`/${boardPath}${isInCatalogView ? '/catalog' : ''}`}>{displayText}</Link> : <span>{displayText}</span>}
|
||||
{index !== total - 1 && ' / '}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.boardNavDesktop}>
|
||||
<span className={styles.boardList}>
|
||||
@@ -97,24 +170,20 @@ const TopBarDesktop = () => {
|
||||
</>
|
||||
)}
|
||||
]{' '}
|
||||
{subscriptions?.length > 0 && (
|
||||
<>
|
||||
[
|
||||
{subscriptions.map((address: any, index: any) => {
|
||||
const boardPath = getBoardPath(address, defaultSubplebbits);
|
||||
const displayText = address.endsWith('.eth') || address.endsWith('.sol') ? address : address.slice(0, 10).concat('...');
|
||||
return (
|
||||
<span key={index}>
|
||||
{index === 0 ? null : ' '}
|
||||
{boardPath && boardPath.trim() ? <Link to={`/${boardPath}${isInCatalogView ? '/catalog' : ''}`}>{displayText}</Link> : <span>{displayText}</span>}
|
||||
{index !== subscriptions?.length - 1 ? ' /' : null}
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
]{' '}
|
||||
</>
|
||||
{BOARD_CODE_GROUPS.map((group, groupIndex) => {
|
||||
const visibleCodes = group.filter((code) => visibleDirectories.has(code));
|
||||
if (visibleCodes.length === 0) return null;
|
||||
|
||||
return <span key={groupIndex}>[{visibleCodes.map((code, codeIndex) => renderBoardCode(code, codeIndex === visibleCodes.length - 1))}] </span>;
|
||||
})}
|
||||
{visibleSubscriptionAddresses.length > 0 && (
|
||||
<>[{visibleSubscriptionAddresses.map((address: string, index: number) => renderSubscription(address, index, visibleSubscriptionAddresses.length))}] </>
|
||||
)}
|
||||
[
|
||||
<span className={styles.temporaryButton} onClick={() => openTopbarEditModal()} style={{ cursor: 'pointer' }}>
|
||||
{_.capitalize(t('edit'))}
|
||||
</span>
|
||||
] [
|
||||
<span className={styles.temporaryButton} onClick={() => openCreateBoardModal()} style={{ cursor: 'pointer' }}>
|
||||
{t('create_board')}
|
||||
</span>
|
||||
|
||||
Reference in New Issue
Block a user