mirror of
https://github.com/plebbit/seedit.git
synced 2026-02-15 16:31:24 -05:00
112
.github/workflows/notifications.yml
vendored
112
.github/workflows/notifications.yml
vendored
@@ -1,19 +1,19 @@
|
||||
# # send notifications to telegram group on commits, releases, issues
|
||||
# name: notifications
|
||||
# send notifications to telegram group on commits, releases, issues
|
||||
name: notifications
|
||||
|
||||
# on:
|
||||
# pull_request:
|
||||
# branches:
|
||||
# - master
|
||||
# push:
|
||||
# branches:
|
||||
# - master
|
||||
# release:
|
||||
# types: [published]
|
||||
# issues:
|
||||
# types: [opened]
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
# push:
|
||||
# branches:
|
||||
# - master
|
||||
release:
|
||||
types: [published]
|
||||
issues:
|
||||
types: [opened]
|
||||
|
||||
# jobs:
|
||||
jobs:
|
||||
# push:
|
||||
# if: ${{ github.event_name == 'push' }}
|
||||
# runs-on: ubuntu-latest
|
||||
@@ -44,50 +44,50 @@
|
||||
# format: html
|
||||
# message_file: message.txt
|
||||
|
||||
# release:
|
||||
# if: ${{ github.event_name == 'release' }}
|
||||
# runs-on: ubuntu-latest
|
||||
# steps:
|
||||
# # - name: debug
|
||||
# # env:
|
||||
# # DEBUG: ${{ toJSON(github) }}
|
||||
# # run: echo "$DEBUG"
|
||||
release:
|
||||
if: ${{ github.event_name == 'release' }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# - name: debug
|
||||
# env:
|
||||
# DEBUG: ${{ toJSON(github) }}
|
||||
# run: echo "$DEBUG"
|
||||
|
||||
# # write message to file
|
||||
# - run: echo "<b>${{ github.event.repository.name }} ${{ github.event.release.name }}</b>" >> message.txt
|
||||
# - run: echo "" >> message.txt
|
||||
# - run: echo "${{ github.event.release.body }}" >> message.txt
|
||||
# - run: echo "${{ github.event.release.html_url }}" >> message.txt
|
||||
# write message to file
|
||||
- run: echo "<b>${{ github.event.repository.name }} ${{ github.event.release.name }}</b>" >> message.txt
|
||||
- run: echo "" >> message.txt
|
||||
- run: echo "${{ github.event.release.body }}" >> message.txt
|
||||
- run: echo "${{ github.event.release.html_url }}" >> message.txt
|
||||
|
||||
# # send message, @plebbit telegram chat id is -1001665335693
|
||||
# - name: "telegram notification"
|
||||
# uses: appleboy/telegram-action@master
|
||||
# with:
|
||||
# to: -1001665335693
|
||||
# token: ${{ secrets.TELEGRAM_TOKEN }}
|
||||
# format: html
|
||||
# message_file: message.txt
|
||||
# send message, @plebbit telegram chat id is -1001665335693
|
||||
- name: "telegram notification"
|
||||
uses: appleboy/telegram-action@master
|
||||
with:
|
||||
to: -1001665335693
|
||||
token: ${{ secrets.TELEGRAM_TOKEN }}
|
||||
format: html
|
||||
message_file: message.txt
|
||||
|
||||
# issue:
|
||||
# if: ${{ github.event_name == 'issues' }}
|
||||
# runs-on: ubuntu-latest
|
||||
# steps:
|
||||
# # - name: debug
|
||||
# # env:
|
||||
# # DEBUG: ${{ toJSON(github) }}
|
||||
# # run: echo "$DEBUG"
|
||||
issue:
|
||||
if: ${{ github.event_name == 'issues' }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# - name: debug
|
||||
# env:
|
||||
# DEBUG: ${{ toJSON(github) }}
|
||||
# run: echo "$DEBUG"
|
||||
|
||||
# # write message to file
|
||||
# - run: echo "<code>${{ github.event.issue.title }}</code>" >> message.txt
|
||||
# - run: echo "" >> message.txt
|
||||
# - run: echo "by <i>${{ github.event.issue.user.login }}</i>" >> message.txt
|
||||
# - run: echo "${{ github.event.issue.html_url }}" >> message.txt
|
||||
# write message to file
|
||||
- run: echo "<code>${{ github.event.issue.title }}</code>" >> message.txt
|
||||
- run: echo "" >> message.txt
|
||||
- run: echo "by <i>${{ github.event.issue.user.login }}</i>" >> message.txt
|
||||
- run: echo "${{ github.event.issue.html_url }}" >> message.txt
|
||||
|
||||
# # send message, @plebbit telegram chat id is -1001665335693
|
||||
# - name: "telegram notification"
|
||||
# uses: appleboy/telegram-action@master
|
||||
# with:
|
||||
# to: -1001665335693
|
||||
# token: ${{ secrets.TELEGRAM_TOKEN }}
|
||||
# format: html
|
||||
# message_file: message.txt
|
||||
# send message, @plebbit telegram chat id is -1001665335693
|
||||
- name: "telegram notification"
|
||||
uses: appleboy/telegram-action@master
|
||||
with:
|
||||
to: -1001665335693
|
||||
token: ${{ secrets.TELEGRAM_TOKEN }}
|
||||
format: html
|
||||
message_file: message.txt
|
||||
|
||||
@@ -42,8 +42,6 @@ const useEditStore = create<EditStoreState>((set) => ({
|
||||
onChallengeVerification: alertChallengeVerificationFailed,
|
||||
onError: (error: Error) => {
|
||||
console.error(error);
|
||||
let errorMessage = error.message;
|
||||
alert(errorMessage);
|
||||
},
|
||||
};
|
||||
return nextState;
|
||||
|
||||
@@ -11,23 +11,23 @@ type ShareMenuProps = {
|
||||
|
||||
const ShareButton = ({ cid, subplebbitAddress }: ShareMenuProps) => {
|
||||
const { t } = useTranslation();
|
||||
const [hasShared, setHasShared] = useState(false);
|
||||
const [hasCopied, setHasCopied] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (hasShared) {
|
||||
setTimeout(() => setHasShared(false), 2000);
|
||||
if (hasCopied) {
|
||||
setTimeout(() => setHasCopied(false), 2000);
|
||||
}
|
||||
}, [hasShared]);
|
||||
}, [hasCopied]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`${!hasShared ? styles.menuItem : styles.text}`}
|
||||
className={`${!hasCopied ? styles.menuItem : styles.text}`}
|
||||
onClick={() => {
|
||||
setHasShared(true);
|
||||
setHasCopied(true);
|
||||
copyShareLinkToClipboard(subplebbitAddress, cid);
|
||||
}}
|
||||
>
|
||||
{hasShared ? t('link_copied') : t('copy_link')}
|
||||
{hasCopied ? t('link_copied') : t('copy_link')}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -59,7 +59,6 @@
|
||||
}
|
||||
|
||||
.xEmbed {
|
||||
width: 400px !important;
|
||||
height: 580px !important;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import styles from './reply-form.module.css';
|
||||
import { isValidURL } from '../../lib/utils/url-utils';
|
||||
import useReply from '../../hooks/use-reply';
|
||||
@@ -10,6 +9,7 @@ type ReplyFormProps = {
|
||||
cid: string;
|
||||
isReplyingToReply?: boolean;
|
||||
hideReplyForm?: () => void;
|
||||
subplebbitAddress: string;
|
||||
};
|
||||
|
||||
export const FormattingHelpTable = () => {
|
||||
@@ -80,11 +80,10 @@ export const FormattingHelpTable = () => {
|
||||
);
|
||||
};
|
||||
|
||||
const ReplyForm = ({ cid, isReplyingToReply, hideReplyForm }: ReplyFormProps) => {
|
||||
const ReplyForm = ({ cid, isReplyingToReply, hideReplyForm, subplebbitAddress }: ReplyFormProps) => {
|
||||
const { t } = useTranslation();
|
||||
const [showOptions, setShowOptions] = useState(false);
|
||||
const [showFormattingHelp, setShowFormattingHelp] = useState(false);
|
||||
const subplebbitAddress = useParams().subplebbitAddress as string;
|
||||
const { setContent, resetContent, replyIndex, publishReply } = useReply({ cid, subplebbitAddress });
|
||||
|
||||
const mdContainerClass = isReplyingToReply ? `${styles.mdContainer} ${styles.mdContainerReplying}` : styles.mdContainer;
|
||||
|
||||
@@ -414,7 +414,7 @@ const Reply = ({ cidOfReplyWithContext, depth = 0, isSingleComment, isSingleRepl
|
||||
showReplyForm={showReplyForm}
|
||||
spoiler={spoiler}
|
||||
/>
|
||||
{isReplying && <ReplyForm cid={cid} isReplyingToReply={true} hideReplyForm={hideReplyForm} />}
|
||||
{isReplying && <ReplyForm cid={cid} isReplyingToReply={true} hideReplyForm={hideReplyForm} subplebbitAddress={subplebbitAddress} />}
|
||||
{!isSingleReply &&
|
||||
replies.map((reply, index) => {
|
||||
return (
|
||||
|
||||
@@ -61,7 +61,7 @@ const Post = ({ post }: { post: Comment }) => {
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.spacer} />
|
||||
{!isSingleComment && <ReplyForm cid={cid} />}
|
||||
{!isSingleComment && <ReplyForm cid={cid} subplebbitAddress={subplebbitAddress} />}
|
||||
{loadingString && loadingString}
|
||||
</div>
|
||||
{isSingleComment && (
|
||||
|
||||
@@ -38,18 +38,23 @@
|
||||
width: 80vw;
|
||||
}
|
||||
|
||||
.infoButton {
|
||||
padding: 0px 4px 0px 4px;
|
||||
font-size: 11px;
|
||||
position: relative;
|
||||
bottom: 2px;
|
||||
margin-bottom: -2px;
|
||||
}
|
||||
|
||||
.copyAddressSetting {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.copyAddressSetting button {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.cryptoAddressInfo {
|
||||
padding: 5px 20px 5px 0;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.cryptoAddressInfo a {
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.cryptoAddressInfo a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
@@ -65,12 +65,6 @@ const AddressSettings = () => {
|
||||
}));
|
||||
}, [resolvedAddress, account?.signer?.address, t]);
|
||||
|
||||
const cryptoAddressInfo = () => {
|
||||
alert(
|
||||
'Change your account address to an ENS name you own: in your ENS name page on ens.domains, click on "Records", "Edit Records", "Add record", add "plebbit-author-address" as record name, add your full address as value (you can copy it from your account data) and save.',
|
||||
);
|
||||
};
|
||||
|
||||
const saveCryptoAddress = async () => {
|
||||
if (!cryptoState.cryptoAddress || !cryptoState.cryptoAddress.includes('.')) {
|
||||
alert(t('enter_crypto_address'));
|
||||
@@ -129,16 +123,11 @@ const AddressSettings = () => {
|
||||
}
|
||||
}, [savedCryptoAddress]);
|
||||
|
||||
const [showCryptoAddressInfo, setShowCryptoAddressInfo] = useState(false);
|
||||
|
||||
return (
|
||||
<div className={styles.addressSettings}>
|
||||
<div className={styles.copyAddressSetting}>
|
||||
<button onClick={() => navigator.clipboard.writeText(account?.signer?.address)}>{t('copy')}</button> plebbit-author-address
|
||||
</div>
|
||||
<div className={styles.cryptoAddressSetting}>
|
||||
<span className={styles.settingTitle}>{t('crypto_address')}</span>
|
||||
<button className={styles.infoButton} onClick={cryptoAddressInfo}>
|
||||
?
|
||||
</button>
|
||||
<div className={styles.usernameInput}>
|
||||
<input
|
||||
type='text'
|
||||
@@ -146,9 +135,20 @@ const AddressSettings = () => {
|
||||
value={cryptoState.cryptoAddress}
|
||||
onChange={(e) => setCryptoState((prevState) => ({ ...prevState, cryptoAddress: e.target.value }))}
|
||||
/>
|
||||
<button className={styles.infoButton} onClick={() => setShowCryptoAddressInfo(!showCryptoAddressInfo)}>
|
||||
{showCryptoAddressInfo ? 'x' : '?'}
|
||||
</button>
|
||||
<button className={styles.button} onClick={saveCryptoAddress}>
|
||||
{t('save')}
|
||||
</button>
|
||||
{showCryptoAddressInfo && (
|
||||
<div className={styles.cryptoAddressInfo}>
|
||||
<a href='https://app.ens.domains/' target='_blank' rel='noopener noreferrer'>
|
||||
app.ens.domains
|
||||
</a>
|
||||
{` > address.eth > records > edit records > add record > record name: "plebbit-author-address" > record value: ${account?.signer?.address} > save`}
|
||||
</div>
|
||||
)}
|
||||
{savedCryptoAddress && <span className={styles.saved}>{t('saved')}</span>}
|
||||
</div>
|
||||
<div className={styles.checkCryptoAddress}>
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
.avatar {
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
border: 1px solid var(--border-text);
|
||||
}
|
||||
|
||||
.avatar img {
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
}
|
||||
|
||||
.emptyAvatar {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.avatarSettingsForm {
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.avatarSettingsForm input {
|
||||
margin-bottom: 10px;
|
||||
width: 200px;
|
||||
padding: 2px;
|
||||
box-shadow: var(--box-shadow-input);
|
||||
}
|
||||
|
||||
.avatarSettingInput input {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.settingTitle {
|
||||
font-style: italic;
|
||||
text-transform: lowercase;
|
||||
}
|
||||
|
||||
.copyMessage {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.pasteSignature span {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.pasteSignature button {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.state {
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.copyMessage a {
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.copyMessage a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
195
src/views/settings/avatar-settings/avatar-settings.tsx
Normal file
195
src/views/settings/avatar-settings/avatar-settings.tsx
Normal file
@@ -0,0 +1,195 @@
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { setAccount, useAccount, useAuthorAvatar } from '@plebbit/plebbit-react-hooks';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import styles from './avatar-settings.module.css';
|
||||
|
||||
interface AvatarSettingsProps {
|
||||
areSettingsShown?: boolean;
|
||||
avatar?: any;
|
||||
showSettings?: () => void;
|
||||
}
|
||||
|
||||
const AvatarPreview = ({ avatar, showSettings, areSettingsShown }: AvatarSettingsProps) => {
|
||||
const { t } = useTranslation();
|
||||
const account = useAccount();
|
||||
let author = useMemo(() => ({ ...account?.author, avatar }), [account, avatar]);
|
||||
|
||||
const { imageUrl, state, error } = useAuthorAvatar({ author });
|
||||
|
||||
// if avatar already set, and user hasn't typed anything yet, preview already set author
|
||||
if (account?.author?.avatar && !avatar?.chainTicker && !avatar?.address && !avatar?.id && !avatar?.signature) {
|
||||
author = account.author;
|
||||
}
|
||||
|
||||
// not enough data to preview yet
|
||||
if (!author?.avatar?.address && !author?.avatar?.signature) {
|
||||
return;
|
||||
}
|
||||
|
||||
const stateText = state !== 'succeeded' ? `${state}...` : undefined;
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={styles.avatar}>
|
||||
{imageUrl && state !== 'initializing' ? (
|
||||
<img src={imageUrl} alt='avatar' />
|
||||
) : (
|
||||
<span className={styles.emptyAvatar} onClick={showSettings}>
|
||||
{areSettingsShown ? '–' + t('hide') : '+' + t('add')}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div className={styles.state}>
|
||||
{stateText} {error?.message}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const AvatarSettings = () => {
|
||||
const [showSettings, setShowSettings] = useState(false);
|
||||
|
||||
const account = useAccount();
|
||||
|
||||
const authorAddress = account?.author?.address;
|
||||
const [chainTicker, setChainTicker] = useState(account?.author?.avatar?.chainTicker);
|
||||
const [tokenAddress, setTokenAddress] = useState(account?.author?.avatar?.address);
|
||||
const [tokenId, setTokenId] = useState(account?.author?.avatar?.id);
|
||||
const [timestamp, setTimestamp] = useState(account?.author?.avatar?.timestamp);
|
||||
const [signature, setSignature] = useState(account?.author?.avatar?.signature?.signature);
|
||||
|
||||
const getNftMessageToSign = (authorAddress: string, timestamp: number, tokenAddress: string, tokenId: string) => {
|
||||
let messageToSign: any = {};
|
||||
// the property names must be in this order for the signature to match
|
||||
// insert props one at a time otherwise babel/webpack will reorder
|
||||
messageToSign.domainSeparator = 'plebbit-author-avatar';
|
||||
messageToSign.authorAddress = authorAddress;
|
||||
messageToSign.timestamp = timestamp;
|
||||
messageToSign.tokenAddress = tokenAddress;
|
||||
messageToSign.tokenId = String(tokenId); // must be a type string, not number
|
||||
// use plain JSON so the user can read what he's signing
|
||||
messageToSign = JSON.stringify(messageToSign);
|
||||
return messageToSign;
|
||||
};
|
||||
|
||||
const [hasCopied, setHasCopied] = useState(false);
|
||||
useEffect(() => {
|
||||
if (hasCopied) {
|
||||
setTimeout(() => setHasCopied(false), 2000);
|
||||
}
|
||||
}, [hasCopied]);
|
||||
|
||||
const copyMessageToSign = () => {
|
||||
if (!chainTicker) {
|
||||
return alert('missing chain ticker');
|
||||
}
|
||||
if (!tokenAddress) {
|
||||
return alert('missing token address');
|
||||
}
|
||||
if (!tokenId) {
|
||||
return alert('missing token id');
|
||||
}
|
||||
const newTimestamp = Math.floor(Date.now() / 1000);
|
||||
const messageToSign = getNftMessageToSign(authorAddress, newTimestamp, tokenAddress, tokenId);
|
||||
// update timestamp every time the user gets a new message to sign
|
||||
setTimestamp(newTimestamp);
|
||||
navigator.clipboard.writeText(messageToSign);
|
||||
setHasCopied(true);
|
||||
};
|
||||
|
||||
// how to resolve and verify NFT signatures https://github.com/plebbit/plebbit-js/blob/master/docs/nft.md
|
||||
const avatar = {
|
||||
chainTicker: chainTicker?.toLowerCase() || account?.author?.avatar?.chainTicker,
|
||||
timestamp,
|
||||
address: tokenAddress || account?.author?.avatar?.address,
|
||||
id: tokenId || account?.author?.avatar?.id,
|
||||
signature: {
|
||||
signature: signature || account?.author?.avatar?.signature?.signature,
|
||||
type: 'eip191',
|
||||
},
|
||||
};
|
||||
|
||||
const save = () => {
|
||||
if (!chainTicker) {
|
||||
return alert('missing chain ticker');
|
||||
}
|
||||
if (!tokenAddress) {
|
||||
return alert('missing token address');
|
||||
}
|
||||
if (!tokenId) {
|
||||
return alert('missing token id');
|
||||
}
|
||||
if (!signature) {
|
||||
return alert('missing signature');
|
||||
}
|
||||
setAccount({ ...account, author: { ...account?.author, avatar } });
|
||||
alert(`saved`);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.avatarSettings}>
|
||||
<AvatarPreview avatar={avatar} showSettings={() => setShowSettings(!showSettings)} areSettingsShown={showSettings} />
|
||||
{showSettings && (
|
||||
<div className={styles.avatarSettingsForm}>
|
||||
<div className={styles.avatarSettingInput}>
|
||||
<span className={styles.settingTitle}>chain ticker</span>
|
||||
<input
|
||||
type='text'
|
||||
placeholder='eth/sol/avax'
|
||||
autoCorrect='off'
|
||||
autoComplete='off'
|
||||
spellCheck='false'
|
||||
defaultValue={account?.author?.avatar?.chainTicker}
|
||||
onChange={(e) => setChainTicker(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.avatarSettingInput}>
|
||||
<span className={styles.settingTitle}>token address</span>
|
||||
<input
|
||||
type='text'
|
||||
placeholder='0x...'
|
||||
autoCorrect='off'
|
||||
autoComplete='off'
|
||||
spellCheck='false'
|
||||
defaultValue={account?.author?.avatar?.address}
|
||||
onChange={(e) => setTokenAddress(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.avatarSettingInput}>
|
||||
<span className={styles.settingTitle}>token id</span>
|
||||
<input
|
||||
type='text'
|
||||
placeholder='Token ID'
|
||||
autoCorrect='off'
|
||||
autoComplete='off'
|
||||
spellCheck='false'
|
||||
defaultValue={account?.author?.avatar?.id}
|
||||
onChange={(e) => setTokenId(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.copyMessage}>
|
||||
<button onClick={copyMessageToSign}>{hasCopied ? 'copied' : 'copy'}</button> message to sign on{' '}
|
||||
<a href='https://etherscan.io/verifiedSignatures' target='_blank' rel='noopener noreferrer'>
|
||||
etherscan
|
||||
</a>
|
||||
</div>
|
||||
<div className={styles.pasteSignature}>
|
||||
<span className={styles.settingTitle}>paste signature</span>
|
||||
<input
|
||||
type='text'
|
||||
placeholder='0x...'
|
||||
autoCorrect='off'
|
||||
autoComplete='off'
|
||||
spellCheck='false'
|
||||
defaultValue={account?.author?.avatar?.signature?.signature}
|
||||
onChange={(e) => setSignature(e.target.value)}
|
||||
/>
|
||||
<button onClick={save}>save</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AvatarSettings;
|
||||
1
src/views/settings/avatar-settings/index.ts
Normal file
1
src/views/settings/avatar-settings/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { default } from './avatar-settings';
|
||||
@@ -75,26 +75,6 @@
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
border: 1px solid var(--border-text);
|
||||
}
|
||||
|
||||
.avatar img {
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
}
|
||||
|
||||
.emptyAvatar {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.usernameInput input {
|
||||
width: 200px;
|
||||
padding: 2px;
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Trans, useTranslation } from 'react-i18next';
|
||||
import { setAccount, useAccount, useAuthorAvatar } from '@plebbit/plebbit-react-hooks';
|
||||
import { setAccount, useAccount } from '@plebbit/plebbit-react-hooks';
|
||||
import styles from './settings.module.css';
|
||||
import AccountSettings from './account-settings';
|
||||
import AddressSettings from './address-settings';
|
||||
import AvatarSettings from './avatar-settings';
|
||||
import useTheme from '../../hooks/use-theme';
|
||||
import packageJson from '../../../package.json';
|
||||
import _ from 'lodash';
|
||||
@@ -106,18 +107,6 @@ const ThemeSettings = () => {
|
||||
);
|
||||
};
|
||||
|
||||
const AvatarSettings = () => {
|
||||
const { t } = useTranslation();
|
||||
const account = useAccount();
|
||||
const { imageUrl } = useAuthorAvatar({ author: account?.author });
|
||||
|
||||
return (
|
||||
<div className={styles.avatarSettings}>
|
||||
<div className={styles.avatar}>{imageUrl ? <img src={imageUrl} alt='avatar' /> : <span className={styles.emptyAvatar}>+{t('add')}</span>}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const DisplayNameSetting = () => {
|
||||
const { t } = useTranslation();
|
||||
const account = useAccount();
|
||||
@@ -233,7 +222,7 @@ const Settings = () => {
|
||||
</span>
|
||||
</div>
|
||||
<div className={styles.category}>
|
||||
<span className={styles.categoryTitle}>{t('address')}</span>
|
||||
<span className={styles.categoryTitle}>{t('crypto_address')}</span>
|
||||
<span className={styles.categorySettings}>
|
||||
<AddressSettings />
|
||||
</span>
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
.readOnlyDescription {
|
||||
font-size: 14px;
|
||||
font-family: verdana, arial, helvetica, sans-serif;
|
||||
word-wrap: break-word;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user