feat(settings): add avatar setting

This commit is contained in:
Tom (plebeius.eth)
2024-07-12 20:22:09 +02:00
parent 9960e400e8
commit f2e4f14a33
47 changed files with 467 additions and 47 deletions
+5 -2
View File
@@ -136,7 +136,7 @@
"collapse_all_settings": "طي جميع الإعدادات",
"refresh": "تحديث",
"no_board_selected": "لم يتم تحديد أية منتديات",
"none": "بلا",
"none": "لا شيء",
"not_subscribed_to_any_board": "لم تشترك في أي منتديات بعد.",
"board_mods": "مشرفو المنتدى",
"this_post_was_removed": "تمت إزالة هذا المنشور",
@@ -213,5 +213,8 @@
"user_banned": "تم حظر المستخدم لهذا المنشور",
"loading_comments": "تحميل التعليقات",
"replies": "الردود",
"links": "الروابط"
"links": "الروابط",
"avatar": "الصورة الرمزية",
"token_address_whitelist": "عنوان الرمز (فقط على الـ <1>قائمة البيضاء</1>)",
"token_id": "تعريف الرمز"
}
+5 -2
View File
@@ -136,7 +136,7 @@
"collapse_all_settings": "সমস্ত সেটিংস সঙ্কুচিত করুন",
"refresh": "পুনরায় লোড করুন",
"no_board_selected": "কোনো ফোরাম নির্বাচিত হয়নি",
"none": "না",
"none": "কিছু না",
"not_subscribed_to_any_board": "আপনি এখনো কোনো ফোরামে সদস্য হননি।",
"board_mods": "বোর্ড মডস",
"this_post_was_removed": "এই পোস্টটি সরানো হয়েছে",
@@ -213,5 +213,8 @@
"user_banned": "এই পোস্টের জন্য ব্যবহারকারী নিষিদ্ধ হয়েছে",
"loading_comments": "মন্তব্য লোড হচ্ছে",
"replies": "উত্তর",
"links": "লিঙ্কগুলি"
"links": "লিঙ্কগুলি",
"avatar": "অবতার",
"token_address_whitelist": "টোকেন ঠিকানা (<1>সাফল্যবান</1> কেবল)",
"token_id": "টোকেন আইডি"
}
+4 -1
View File
@@ -213,5 +213,8 @@
"user_banned": "Uživatel byl zablokován za tento příspěvek",
"loading_comments": "Načítání komentářů",
"replies": "Odpovědi",
"links": "Odkazy"
"links": "Odkazy",
"avatar": "avatar",
"token_address_whitelist": "Tokenová adresa (<1>jen bílý seznam</1>)",
"token_id": "Token ID"
}
+4 -1
View File
@@ -213,5 +213,8 @@
"user_banned": "Brugeren blev blokeret for dette indlæg",
"loading_comments": "Indlæser kommentarer",
"replies": "Svar",
"links": "Links"
"links": "Links",
"avatar": "avatar",
"token_address_whitelist": "Tokenadresse (<1>kun hvidliste</1>)",
"token_id": "Token ID"
}
+4 -1
View File
@@ -213,5 +213,8 @@
"user_banned": "Benutzer wurde für diesen Beitrag gesperrt",
"loading_comments": "Lade Kommentare",
"replies": "Antworten",
"links": "Links"
"links": "Links",
"avatar": "Avatar",
"token_address_whitelist": "Tokenadresse (<1>nur Weiße Liste</1>)",
"token_id": "Token-ID"
}
+4 -1
View File
@@ -213,5 +213,8 @@
"user_banned": "Ο χρήστης αποκλείστηκε για αυτή τη δημοσίευση",
"loading_comments": "Φόρτωση σχολίων",
"replies": "Απαντήσεις",
"links": "Σύνδεσμοι"
"links": "Σύνδεσμοι",
"avatar": "εικόνα προφίλ",
"token_address_whitelist": "Διεύθυνση του token (<1>μόνο λευκή λίστα</1>)",
"token_id": "Token ID"
}
+4 -1
View File
@@ -213,5 +213,8 @@
"user_banned": "User was banned for this post",
"loading_comments": "Loading comments",
"replies": "replies",
"links": "links"
"links": "links",
"avatar": "avatar",
"token_address_whitelist": "Token address (<1>whitelist</1> only)",
"token_id": "token id"
}
+4 -1
View File
@@ -213,5 +213,8 @@
"user_banned": "El usuario fue baneado por esta publicación",
"loading_comments": "Cargando comentarios",
"replies": "respuestas",
"links": "enlaces"
"links": "enlaces",
"avatar": "avatar",
"token_address_whitelist": "Dirección del token (<1>solo lista blanca</1>)",
"token_id": "ID de token"
}
+5 -2
View File
@@ -136,7 +136,7 @@
"collapse_all_settings": "تايید همه تنظیمات",
"refresh": "تازه‌سازی",
"no_board_selected": "هیچ تالاری انتخاب نشده است",
"none": "هیچکدام",
"none": "هیچکدام",
"not_subscribed_to_any_board": "هنوز به هیچ تالاری مشترک نشده‌اید.",
"board_mods": "مدیران تالار",
"this_post_was_removed": "این پست حذف شد",
@@ -213,5 +213,8 @@
"user_banned": "این کاربر برای این پست مسدود شد",
"loading_comments": "بارگذاری نظرات",
"replies": "پاسخ‌ها",
"links": "لینک‌ها"
"links": "لینک‌ها",
"avatar": "آواتار",
"token_address_whitelist": "آدرس توکن (<1>فقط سفیدپوشان</1>)",
"token_id": "شناسه توکن"
}
+5 -2
View File
@@ -136,7 +136,7 @@
"collapse_all_settings": "Sulje kaikki asetukset",
"refresh": "Päivitä",
"no_board_selected": "ei foorumeja valittu",
"none": "ei mikään",
"none": "ei mitään",
"not_subscribed_to_any_board": "Et ole vielä tilannut mitään foorumeita.",
"board_mods": "Hallituksen Mods",
"this_post_was_removed": "tämä viesti on poistettu",
@@ -213,5 +213,8 @@
"user_banned": "Käyttäjä on estetty tästä viestistä",
"loading_comments": "Ladataan kommentteja",
"replies": "vastaukset",
"links": "linkit"
"links": "linkit",
"avatar": "avatar",
"token_address_whitelist": "Token-osoite (<1>vain valkoinen lista</1>)",
"token_id": "Token-id"
}
+5 -2
View File
@@ -136,7 +136,7 @@
"collapse_all_settings": "I-collapse ang lahat ng mga setting",
"refresh": "I-refresh",
"no_board_selected": "walang mga board na napiling",
"none": "wala",
"none": "walang anuman",
"not_subscribed_to_any_board": "Hindi ka pa naka-subscribe sa anumang mga board.",
"board_mods": "Board Mods",
"this_post_was_removed": "tinanggal ang post na ito",
@@ -213,5 +213,8 @@
"user_banned": "Banal ang user para sa post na ito",
"loading_comments": "Naglo-load ng mga komento",
"replies": "mga tugon",
"links": "mga link"
"links": "mga link",
"avatar": "avatar",
"token_address_whitelist": "Address ng token (<1>whitelist</1> lang)",
"token_id": "Token ID"
}
+4 -1
View File
@@ -213,5 +213,8 @@
"user_banned": "L'utilisateur a été banni pour ce post",
"loading_comments": "Chargement des commentaires",
"replies": "réponses",
"links": "liens"
"links": "liens",
"avatar": "avatar",
"token_address_whitelist": "Adresse du token (<1>liste blanche</1> seulement)",
"token_id": "Identifiant de jeton"
}
+4 -1
View File
@@ -213,5 +213,8 @@
"user_banned": "המשתמש נחסם עבור הפוסט הזה",
"loading_comments": "טוען תגובות",
"replies": "תגובות",
"links": "קישורים"
"links": "קישורים",
"avatar": "אוואטר",
"token_address_whitelist": "כתובת הטוקן (<1>רק רשימה לבנה</1>)",
"token_id": "מזהה טוקן"
}
+4 -1
View File
@@ -213,5 +213,8 @@
"user_banned": "इस पोस्ट के लिए उपयोगकर्ता पर प्रतिबंध लगा दिया गया था",
"loading_comments": "टिप्पणियाँ लोड हो रही हैं",
"replies": "जवाब",
"links": "लिंक"
"links": "लिंक",
"avatar": "अवतार",
"token_address_whitelist": "टोकन पता (<1>केवल सफेद सूची</1>)",
"token_id": "टोकन आईडी"
}
+4 -1
View File
@@ -213,5 +213,8 @@
"user_banned": "A felhasználót letiltották ennek a posztnak a kapcsán",
"loading_comments": "Megjegyzések betöltése",
"replies": "válaszok",
"links": "linkek"
"links": "linkek",
"avatar": "avatár",
"token_address_whitelist": "Token cím (<1>csak fehérlista</1>)",
"token_id": "Token azonosító"
}
+5 -2
View File
@@ -136,7 +136,7 @@
"collapse_all_settings": "Ciutkan Semua Pengaturan",
"refresh": "Segarkan",
"no_board_selected": "tidak ada papan pesan yang dipilih",
"none": "tak ada",
"none": "tidak ada",
"not_subscribed_to_any_board": "Anda belum berlangganan ke papan pesan mana pun.",
"board_mods": "Papan Pesan Mods",
"this_post_was_removed": "posting ini telah dihapus",
@@ -213,5 +213,8 @@
"user_banned": "Pengguna diblokir untuk pos ini",
"loading_comments": "Memuat komentar",
"replies": "balasan",
"links": "tautan"
"links": "tautan",
"avatar": "avatar",
"token_address_whitelist": "Alamat token (<1>hanya daftar putih</1>)",
"token_id": "ID token"
}
+4 -1
View File
@@ -213,5 +213,8 @@
"user_banned": "L'utente è stato bannato per questo post",
"loading_comments": "Caricamento commenti",
"replies": "commenti",
"links": "link"
"links": "link",
"avatar": "avatar",
"token_address_whitelist": "Indirizzo del token (solo se sulla <1>whitelist</1>)",
"token_id": "token id"
}
+4 -1
View File
@@ -213,5 +213,8 @@
"user_banned": "この投稿のためにユーザーが禁止されました",
"loading_comments": "コメントを読み込み中",
"replies": "返信",
"links": "リンク"
"links": "リンク",
"avatar": "アバター",
"token_address_whitelist": "トークンアドレス(<1>ホワイトリスト</1>のみ)",
"token_id": "トークンID"
}
+4 -1
View File
@@ -213,5 +213,8 @@
"user_banned": "이 게시물로 인해 사용자가 차단되었습니다",
"loading_comments": "댓글 로드 중",
"replies": "답글",
"links": "링크"
"links": "링크",
"avatar": "아바타",
"token_address_whitelist": "토큰 주소 (<1>화이트리스트</1>만)",
"token_id": "토큰 ID"
}
+5 -2
View File
@@ -136,7 +136,7 @@
"collapse_all_settings": "सर्व सेटिंग्ज संक्षेपित",
"refresh": "ताजेतर करा",
"no_board_selected": "कोणतेही संदेश फलक निवडले नाहीत",
"none": "काहीही नाही",
"none": "काही नाही",
"not_subscribed_to_any_board": "तुम्ही कोणत्याही संदेश फलकांवर अद्याप सदस्यता घेतली नाही.",
"board_mods": "बोर्ड मॉड्स",
"this_post_was_removed": "हा पोस्ट काढून टाकला गेला आहे",
@@ -213,5 +213,8 @@
"user_banned": "या पोस्टसाठी वापरकर्ता ब्लॉक केला गेला होता",
"loading_comments": "टिप्पणी लोड होत आहे",
"replies": "उत्तर",
"links": "लिंक"
"links": "लिंक",
"avatar": "अवतार",
"token_address_whitelist": "टोकन पत्ता (<1>केवळ सफेद सूची</1>)",
"token_id": "टोकन आयडी"
}
+4 -1
View File
@@ -213,5 +213,8 @@
"user_banned": "Gebruiker is verbannen voor deze post",
"loading_comments": "Reacties laden",
"replies": "reacties",
"links": "links"
"links": "links",
"avatar": "avatar",
"token_address_whitelist": "Tokenadres (<1>alleen whitelist</1>)",
"token_id": "Token-ID"
}
+4 -1
View File
@@ -213,5 +213,8 @@
"user_banned": "Brukeren ble utestengt for dette innlegget",
"loading_comments": "Laster inn kommentarer",
"replies": "svar",
"links": "lenker"
"links": "lenker",
"avatar": "avatar",
"token_address_whitelist": "Tokenadresse (<1>kun hvitelisten</1>)",
"token_id": "Token ID"
}
+4 -1
View File
@@ -213,5 +213,8 @@
"user_banned": "Użytkownik został zablokowany za ten post",
"loading_comments": "Ładowanie komentarzy",
"replies": "odpowiedzi",
"links": "linki"
"links": "linki",
"avatar": "avatar",
"token_address_whitelist": "Adres tokenu (<1>tylko biała lista</1>)",
"token_id": "Identyfikator tokena"
}
+4 -1
View File
@@ -213,5 +213,8 @@
"user_banned": "O usuário foi banido por este post",
"loading_comments": "Carregando comentários",
"replies": "respostas",
"links": "links"
"links": "links",
"avatar": "avatar",
"token_address_whitelist": "Endereço do token (<1>apenas lista branca</1>)",
"token_id": "ID do token"
}
+4 -1
View File
@@ -213,5 +213,8 @@
"user_banned": "Utilizatorul a fost interzis pentru acest mesaj",
"loading_comments": "Se încarcă comentariile",
"replies": "răspunsuri",
"links": "linkuri"
"links": "linkuri",
"avatar": "avatar",
"token_address_whitelist": "Adresa tokenului (<1>doar lista albă</1>)",
"token_id": "ID token"
}
+5 -2
View File
@@ -136,7 +136,7 @@
"collapse_all_settings": "Свернуть все настройки",
"refresh": "Обновить",
"no_board_selected": "не выбрано ни одного форума",
"none": ет",
"none": ичего",
"not_subscribed_to_any_board": "Вы еще не подписаны ни на один форум.",
"board_mods": "Модераторы форума",
"this_post_was_removed": "этот пост был удален",
@@ -213,5 +213,8 @@
"user_banned": "Пользователь был заблокирован за этот пост",
"loading_comments": "Загрузка комментариев",
"replies": "ответы",
"links": "ссылки"
"links": "ссылки",
"avatar": "аватар",
"token_address_whitelist": "Адрес токена (<1>только белый список</1>)",
"token_id": "Идентификатор токена"
}
+4 -1
View File
@@ -213,5 +213,8 @@
"user_banned": "Përdoruesi u ndalua për këtë postim",
"loading_comments": "Duke u ngarkuar komentet",
"replies": "përgjigje",
"links": "lidhje"
"links": "lidhje",
"avatar": "avatar",
"token_address_whitelist": "Adresa e tokenit (<1>vetëm lista e bardhë</1>)",
"token_id": "ID e tokenit"
}
+4 -1
View File
@@ -213,5 +213,8 @@
"user_banned": "Användaren blev blockerad för detta inlägg",
"loading_comments": "Laddar kommentarer",
"replies": "svar",
"links": "länkar"
"links": "länkar",
"avatar": "avatar",
"token_address_whitelist": "Tokenadress (<1>endast vitlista</1>)",
"token_id": "Token ID"
}
+5 -2
View File
@@ -136,7 +136,7 @@
"collapse_all_settings": "అన్ని సెట్టింగ్‌లను సంక్షిప్తము చేయండి",
"refresh": "రీఫ్రెష్",
"no_board_selected": "ఏటీ ఎలాంటి సందేశ బోర్డులు ఎంచుకోలేదు",
"none": "ఏమీ లేు",
"none": "ఎవరూ లేు",
"not_subscribed_to_any_board": "మీరు ఇంకా ఏకైక సందేశ బోర్డులకు చేరలేదు.",
"board_mods": "సందేశ బోర్డుల మాడ్స్",
"this_post_was_removed": "ఈ పోస్టు తొలగించబడింది",
@@ -213,5 +213,8 @@
"user_banned": "ఈ పోస్టు కోసం వాడు బ్యాన్ చేయబడింది",
"loading_comments": "వ్యాఖ్యలను లోడ్ అవుతోంది",
"replies": "సమాధానాలు",
"links": "లింక్లు"
"links": "లింక్లు",
"avatar": "అవతార్",
"token_address_whitelist": "టోకెన్ చిరునామా (<1>కేవలం వెలుపల్లి</1>)",
"token_id": "టోకెన్ ఐడి"
}
+4 -1
View File
@@ -213,5 +213,8 @@
"user_banned": "ผู้ใช้ถูกห้ามใช้งานสำหรับโพสต์นี้",
"loading_comments": "กำลังโหลดความคิดเห็น",
"replies": "คำตอบ",
"links": "ลิงก์"
"links": "ลิงก์",
"avatar": "อวตาร์",
"token_address_whitelist": "ที่อยู่โทเค็น (<1>รายชื่อที่ได้รับอนุญาตเท่านั้น</1>)",
"token_id": "รหัสโทเค็น"
}
+4 -1
View File
@@ -213,5 +213,8 @@
"user_banned": "Kullanıcı bu gönderi için yasaklandı",
"loading_comments": "Yorumlar yükleniyor",
"replies": "cevaplar",
"links": "bağlantılar"
"links": "bağlantılar",
"avatar": "avatar",
"token_address_whitelist": "Token adresi (<1>yalnızca beyaz liste</1>)",
"token_id": "Token kimliği"
}
+5 -2
View File
@@ -136,7 +136,7 @@
"collapse_all_settings": "Згорнути всі налаштування",
"refresh": "Оновити",
"no_board_selected": "не обрано жодного форуму",
"none": емає",
"none": іхто",
"not_subscribed_to_any_board": "Ви ще не підписалися на жоден форум.",
"board_mods": "Дошка Моди",
"this_post_was_removed": "цей пост було видалено",
@@ -213,5 +213,8 @@
"user_banned": "Користувач був заблокований за цей пост",
"loading_comments": "Завантаження коментарів",
"replies": "відповіді",
"links": "посилання"
"links": "посилання",
"avatar": "аватар",
"token_address_whitelist": "Адреса токена (<1>тільки білий список</1>)",
"token_id": "Ідентифікатор токена"
}
+4 -1
View File
@@ -213,5 +213,8 @@
"user_banned": "اس پوسٹ کے لئے صارف کو پابندی عائد کردی گئی تھی",
"loading_comments": "تبصرے لوڈ ہو رہے ہیں",
"replies": "جوابات",
"links": "لنکس"
"links": "لنکس",
"avatar": "اوتار",
"token_address_whitelist": "ٹوکن کا پتا (<1>صرف سفید فہرست</1>)",
"token_id": "ٹوکن شناخت"
}
+4 -1
View File
@@ -213,5 +213,8 @@
"user_banned": "Người dùng đã bị cấm vì bài đăng này",
"loading_comments": "Đang tải bình luận",
"replies": "trả lời",
"links": "liên kết"
"links": "liên kết",
"avatar": "avatar",
"token_address_whitelist": "Địa chỉ token (<1>chỉ danh sách trắng</1>)",
"token_id": "ID token"
}
+5 -2
View File
@@ -136,7 +136,7 @@
"collapse_all_settings": "折叠所有设置",
"refresh": "刷新",
"no_board_selected": "没有选择任何论坛",
"none": "",
"none": "没有",
"not_subscribed_to_any_board": "您尚未订阅任何论坛。",
"board_mods": "董事會版主",
"this_post_was_removed": "此帖已被删除",
@@ -213,5 +213,8 @@
"user_banned": "用户因此帖子被禁止",
"loading_comments": "正在加载评论",
"replies": "回复",
"links": "链接"
"links": "链接",
"avatar": "头像",
"token_address_whitelist": "代币地址(<1>仅限白名单</1>",
"token_id": "令牌ID"
}
+1 -1
View File
@@ -3,7 +3,7 @@ import { createPortal } from 'react-dom';
import { useTranslation } from 'react-i18next';
import { Link, useLocation, useParams } from 'react-router-dom';
import { Comment, useComment } from '@plebbit/plebbit-react-hooks';
import { useFloating, offset, shift, size, autoUpdate, Placement } from '@floating-ui/react';
import { useFloating, offset, size, autoUpdate, Placement } from '@floating-ui/react';
import { getCommentMediaInfo, getHasThumbnail } from '../../lib/utils/media-utils';
import { getFormattedTimeAgo } from '../../lib/utils/time-utils';
import { isAllView } from '../../lib/utils/view-utils';
@@ -130,6 +130,7 @@ const AccountSettings = () => {
await importAccount(fileContent);
setSwitchToLastAccount(true);
alert(`Imported ${newAccount.account?.name}`);
window.location.reload();
};
reader.readAsText(file);
} catch (error) {
@@ -0,0 +1,86 @@
.avatar {
width: 70px;
height: 70px;
border: 1px solid #aaa;
background-color: var(--avatar-background-color, white);
margin-left: 10px;
}
.avatarPreview {
display: inline-block;
}
.avatar img {
width: 70px;
height: 70px;
}
.emptyAvatar {
display: flex;
justify-content: center;
align-items: center;
text-align: center;
height: 100%;
color: var(--avatar-text-color);
cursor: pointer;
}
.avatarSettingsForm {
padding: 10px 0 15px 10px;
}
.avatarSettingsForm input {
width: 200px;
padding: 2px;
}
.avatarSettingInput input {
margin-bottom: 10px;
display: block;
}
.avatarSettingInput a {
color: var(--link-primary);
}
.avatarSettingInput a {
color: var(--post-link-text-color);
text-decoration: var(--post-content-link-text-decoration);
}
.avatarSettingInput a:hover {
color: var(--post-link-text-color-hover);
text-decoration: var(--post-content-link-text-decoration-hover);
}
.settingTitle {
font-style: italic;
text-transform: lowercase;
}
.copyMessage {
padding-bottom: 10px;
}
.pasteSignature span {
display: block;
}
.pasteSignature button {
margin-left: 5px;
}
.state {
padding-top: 10px;
padding-left: 10px;
max-width: 300px;
color: var(--post-mobile-abbr-text-color);
}
.copyMessage a {
color: var(--text-primary);
}
.copyMessage a:hover {
text-decoration: underline;
}
@@ -0,0 +1,200 @@
import { useMemo, useState } from 'react';
import { Link } from 'react-router-dom';
import { setAccount, useAccount, useAuthorAvatar } from '@plebbit/plebbit-react-hooks';
import styles from './avatar-settings.module.css';
import { Trans, useTranslation } from 'react-i18next';
import LoadingEllipsis from '../../loading-ellipsis';
const AvatarPreview = ({ avatar }: any) => {
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' ? <LoadingEllipsis string={state} /> : undefined;
return (
<>
<div className={styles.avatar}>
{imageUrl && state !== 'initializing' ? <img src={imageUrl} alt='' /> : <span className={styles.emptyAvatar}>{t('none')}</span>}
</div>
{state !== 'succeeded' && account?.author?.avatar && (
<div className={styles.state}>
{stateText} {error?.message}
</div>
)}
</>
);
};
const AvatarSettings = () => {
const { t } = useTranslation();
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);
const copyMessageToSign = () => {
if (!chainTicker) {
return alert(t('missing_chain_ticker'));
}
if (!tokenAddress) {
return alert(t('missing_token_address'));
}
if (!tokenId) {
return alert(t('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);
setTimeout(() => {
setHasCopied(false);
}, 2000);
};
// 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(t('missing_chain_ticker'));
}
if (!tokenAddress) {
return alert(t('missing_token_address'));
}
if (!tokenId) {
return alert(t('missing_token_id'));
}
if (!signature) {
return alert(t('missing_signature'));
}
setAccount({ ...account, author: { ...account?.author, avatar } });
alert(`saved`);
};
return (
<div className={styles.avatarSettings}>
<AvatarPreview avatar={avatar} />
<div className={styles.avatarSettingsForm}>
<div className={styles.avatarSettingInput}>
<span className={styles.settingTitle}>{t('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}>
<Trans
i18nKey='token_address_whitelist'
shouldUnescape={true}
components={{
1: (
<Link
to='https://github.com/plebbit/plebbit-react-hooks/blob/557cc3f40b5933a00553ed9c0bc310d2cd7a3b52/src/hooks/authors/author-avatars.ts#L133'
target='_blank'
rel='noopener noreferrer'
/>
),
}}
/>
</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}>{t('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}>
<Trans
i18nKey='copy_message_etherscan'
values={{ copy: hasCopied ? t('copied') : t('copy') }}
components={{
1: <button onClick={copyMessageToSign} />,
// eslint-disable-next-line
2: <a href='https://etherscan.io/verifiedSignatures' target='_blank' rel='noopener noreferrer' />,
}}
/>
</div>
<div className={styles.pasteSignature}>
<span className={styles.settingTitle}>{t('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}>{t('save')}</button>
</div>
</div>
</div>
);
};
export default AvatarSettings;
@@ -0,0 +1 @@
export { default } from './avatar-settings';
@@ -193,6 +193,7 @@ const PlebbitOptions = () => {
},
});
alert('Options saved.');
window.location.reload();
} catch (e) {
if (e instanceof Error) {
alert('Error saving options: ' + e.message);
@@ -22,6 +22,10 @@
padding: 2px 4px 3px;
}
.settingsModal input[type="text"]:focus, .settingsModal textarea:focus {
border: var(--reply-modal-field-input-border-focus, revert);
}
.settingsModal {
top: 25px;
left: 50%;
@@ -3,6 +3,7 @@ import { useNavigate } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import styles from './settings-modal.module.css';
import AccountSettings from './account-settings';
import AvatarSettings from './avatar-settings';
import BlockedAddressesSetting from './blocked-addresses-setting';
import CryptoAddressSetting from './crypto-address-setting';
import CryptoWalletsSetting from './crypto-wallets-setting';
@@ -19,6 +20,7 @@ const SettingsModal = () => {
const [showInterfaceSettings, setShowInterfaceSettings] = useState(false);
const [showAccountSettings, setShowAccountSettings] = useState(false);
const [showAvatarSettings, setShowAvatarSettings] = useState(false);
const [showCryptoAddressSetting, setShowCryptoAddressSetting] = useState(false);
const [showCryptoWalletSettings, setShowCryptoWalletSettings] = useState(false);
const [showBlockedAddressesSetting, setShowBlockedAddressesSetting] = useState(false);
@@ -30,6 +32,7 @@ const SettingsModal = () => {
setExpandAll(newExpandState);
setShowInterfaceSettings(newExpandState);
setShowAccountSettings(newExpandState);
setShowAvatarSettings(newExpandState);
setShowCryptoAddressSetting(newExpandState);
setShowCryptoWalletSettings(newExpandState);
setShowBlockedAddressesSetting(newExpandState);
@@ -61,6 +64,13 @@ const SettingsModal = () => {
</label>
</div>
{showAccountSettings && <AccountSettings />}
<div className={`${styles.setting} ${styles.category}`}>
<label onClick={() => setShowAvatarSettings(!showAvatarSettings)}>
<span className={showAvatarSettings ? styles.hideButton : styles.showButton} />
{t('avatar')}
</label>
</div>
{showAvatarSettings && <AvatarSettings />}
<div className={`${styles.setting} ${styles.category}`}>
<label onClick={() => setShowCryptoAddressSetting(!showCryptoAddressSetting)}>
<span className={showCryptoAddressSetting ? styles.hideButton : styles.showButton} />
@@ -26,6 +26,7 @@ const SubplebbitDescription = ({ avatarUrl, createdAt, description, shortAddress
author: { displayName: `## ${t('board_mods')}` },
content: isInAllView ? multisubMetadata?.description : description,
link: avatarUrl,
replyCount: 0,
title: t('welcome_to_board', {
board: isInAllView ? multisubMetadata?.title : title || `p/${shortAddress}`,
interpolation: { escapeValue: false },
@@ -17,6 +17,7 @@ const SubplebbitRules = ({ subplebbitAddress, createdAt, rules }: RulesPostProps
timestamp: createdAt,
author: { displayName: `## ${t('board_mods')}` },
content,
replyCount: 0,
title: _.capitalize(t('rules')),
pinned: true,
locked: true,
+1
View File
@@ -34,6 +34,7 @@ i18next
'eu',
'fa',
'fi',
'fil',
'fr',
'fy',
'ga',
+9
View File
@@ -1,5 +1,8 @@
:root .yotsuba {
--color-scheme: light;
/* avatar */
--avatar-text-color: black;
/* backlink */
--post-backlink-text-color: navy;
@@ -415,6 +418,9 @@
:root .futaba {
--color-scheme: light;
/* avatar */
--avatar-text-color: black;
/* backlink */
--post-backlink-text-color: navy;
--post-backlink-text-decoration: underline;
@@ -772,6 +778,9 @@
:root .tomorrow {
--color-scheme: dark;
/* avatar */
--avatar-background-color: black;
/* backlink */
--post-backlink-text-color: #5f89ac;