Merge pull request #160 from plebbit/development

Development
This commit is contained in:
plebeius.eth
2024-01-03 12:32:01 +01:00
committed by GitHub
50 changed files with 599 additions and 86 deletions

View File

@@ -172,5 +172,9 @@
"no_posts": "لا توجد مشاركات",
"media_url": "عنوان وسائط",
"post_locked_info": "هذا المنشور مغلق. لن تتمكن من التعليق.",
"no_subscriptions_notice": "لم تنضم إلى أي مجتمع بعد."
"no_subscriptions_notice": "لم تنضم إلى أي مجتمع بعد.",
"members_count": "{{count}} أعضاء",
"communities": "مجتمع",
"edit": "تعديل",
"moderator": "مشرف"
}

View File

@@ -172,5 +172,9 @@
"no_posts": "কোন পোস্ট নেই",
"media_url": "মিডিয়া ইউআরএল",
"post_locked_info": "এই পোস্টটি লক হয়েছে। আপনি মন্তব্য করতে পারবেন না।",
"no_subscriptions_notice": "আপনি এখনো কোনও সম্প্রদানে যোগ দিননি।"
"no_subscriptions_notice": "আপনি এখনো কোনও সম্প্রদানে যোগ দিননি।",
"members_count": "{{count}} সদস্য",
"communities": "সম্প্রদান",
"edit": "সম্পাদনা",
"moderator": "মডারেটর"
}

View File

@@ -172,5 +172,9 @@
"no_posts": "žádné příspěvky",
"media_url": "URL médií",
"post_locked_info": "Tento příspěvek je uzamčen. Nebudete moci komentovat.",
"no_subscriptions_notice": "Dosud jste se nepřipojili k žádné komunitě."
"no_subscriptions_notice": "Dosud jste se nepřipojili k žádné komunitě.",
"members_count": "{{count}} členů",
"communities": "komunita",
"edit": "upravit",
"moderator": "Moderátor"
}

View File

@@ -172,5 +172,9 @@
"no_posts": "ingen indlæg",
"media_url": "medie-URL",
"post_locked_info": "Dette indlæg er låst. Du kan ikke kommentere.",
"no_subscriptions_notice": "Du har endnu ikke tilsluttet dig nogen fællesskab."
"no_subscriptions_notice": "Du har endnu ikke tilsluttet dig nogen fællesskab.",
"members_count": "{{count}} medlemmer",
"communities": "fællesskab",
"edit": "redigere",
"moderator": "Moderator"
}

View File

@@ -172,5 +172,9 @@
"no_posts": "keine Beiträge",
"media_url": "Medien-URL",
"post_locked_info": "Dieser Beitrag ist gesperrt. Sie können keine Kommentare abgeben.",
"no_subscriptions_notice": "Du hast dich noch keiner Community angeschlossen."
"no_subscriptions_notice": "Du hast dich noch keiner Community angeschlossen.",
"members_count": "{{count}} Mitglieder",
"communities": "Gemeinschaft",
"edit": "bearbeiten",
"moderator": "Moderator"
}

View File

@@ -172,5 +172,9 @@
"no_posts": "κανένα άρθρο",
"media_url": "URL πολυμέσων",
"post_locked_info": "Αυτή η ανάρτηση είναι κλειδωμένη. Δεν θα μπορείτε να σχολιάσετε.",
"no_subscriptions_notice": "Δεν έχετε εγγραφεί ακόμη σε κοινότητα."
"no_subscriptions_notice": "Δεν έχετε εγγραφεί ακόμη σε κοινότητα.",
"members_count": "{{count}} μέλη",
"communities": "κοινόνια",
"edit": "επικοινωνιακό",
"moderator": "Διαμεσολαβητής"
}

View File

@@ -172,5 +172,9 @@
"no_posts": "no posts",
"media_url": "media url",
"post_locked_info": "This post is locked. You won't be able to comment.",
"no_subscriptions_notice": "You haven't joined any community."
"no_subscriptions_notice": "You haven't joined any community.",
"members_count": "{{count}} members",
"communities": "communities",
"edit": "edit",
"moderator": "Moderator"
}

View File

@@ -172,5 +172,9 @@
"no_posts": "sin publicaciones",
"media_url": "URL de medios",
"post_locked_info": "Esta publicación está bloqueada. No podrás comentar.",
"no_subscriptions_notice": "Todavía no te has unido a ninguna comunidad."
"no_subscriptions_notice": "Todavía no te has unido a ninguna comunidad.",
"members_count": "{{count}} miembros",
"communities": "comunidades",
"edit": "editar",
"moderator": "Moderador"
}

View File

@@ -172,5 +172,9 @@
"no_posts": "بدون پست",
"media_url": "آدرس رسانه",
"post_locked_info": "این پست قفل شده است. نمی‌توانید نظر دهید.",
"no_subscriptions_notice": "هنوز به هیچ انجمنی پیوسته نشده‌اید."
"no_subscriptions_notice": "هنوز به هیچ انجمنی پیوسته نشده‌اید.",
"members_count": "{{count}} عضو",
"communities": "انجمن",
"edit": "ویرایش",
"moderator": "مدیر"
}

View File

@@ -172,5 +172,9 @@
"no_posts": "ei viestejä",
"media_url": "medialinkki",
"post_locked_info": "Tämä viesti on lukittu. Et voi kommentoida sitä.",
"no_subscriptions_notice": "Et ole vielä liittynyt mihinkään yhteisöön."
"no_subscriptions_notice": "Et ole vielä liittynyt mihinkään yhteisöön.",
"members_count": "{{count}} jäsentä",
"communities": "yhteisö",
"edit": "muokata",
"moderator": "Moderaattori"
}

View File

@@ -172,5 +172,9 @@
"no_posts": "walang post",
"media_url": "media url",
"post_locked_info": "Ang post na ito ay naka-lock. Hindi ka makakapagkomento.",
"no_subscriptions_notice": "Hindi ka pa sumali sa anumang komunidad."
"no_subscriptions_notice": "Hindi ka pa sumali sa anumang komunidad.",
"members_count": "{{count}} miyembro",
"communities": "komunidad",
"edit": "ipunin",
"moderator": "Moderator"
}

View File

@@ -172,5 +172,9 @@
"no_posts": "pas de publications",
"media_url": "URL multimédia",
"post_locked_info": "Ce post est verrouillé. Vous ne pourrez pas commenter.",
"no_subscriptions_notice": "Vous n'avez rejoint aucune communauté."
"no_subscriptions_notice": "Vous n'avez rejoint aucune communauté.",
"members_count": "{{count}} membres",
"communities": "communauté",
"edit": "modifier",
"moderator": "Modérateur"
}

View File

@@ -172,5 +172,9 @@
"no_posts": "אין פוסטים",
"media_url": "כתובת מדיה",
"post_locked_info": "הפוסט הזה נעול. אינך יכול להגיב.",
"no_subscriptions_notice": "עדיין לא הצטרפת לאף קהילה."
"no_subscriptions_notice": "עדיין לא הצטרפת לאף קהילה.",
"members_count": "{{count}} חברים",
"communities": "קהילה",
"edit": "עריכה",
"moderator": "מנהל"
}

View File

@@ -172,5 +172,9 @@
"no_posts": "कोई पोस्ट नहीं",
"media_url": "मीडिया यूआरएल",
"post_locked_info": "यह पोस्ट बंद है। आप टिप्पणी नहीं कर सकेंगे।",
"no_subscriptions_notice": "आपने अब तक किसी समुदाय में शामिल नहीं हुए हैं।"
"no_subscriptions_notice": "आपने अब तक किसी समुदाय में शामिल नहीं हुए हैं।",
"members_count": "{{count}} सदस्य",
"communities": "समुदाय",
"edit": "संपादित करें",
"moderator": "मॉडरेटर"
}

View File

@@ -172,5 +172,9 @@
"no_posts": "nincsenek hozzászólások",
"media_url": "média URL",
"post_locked_info": "Ez a bejegyzés zárolva van. Nem fogsz tudni hozzászólni.",
"no_subscriptions_notice": "Még nem csatlakoztál egyetlen közösséghez sem."
"no_subscriptions_notice": "Még nem csatlakoztál egyetlen közösséghez sem.",
"members_count": "{{count}} tag",
"communities": "közösség",
"edit": "szerkesztés",
"moderator": "Moderátor"
}

View File

@@ -172,5 +172,9 @@
"no_posts": "tidak ada posting",
"media_url": "URL media",
"post_locked_info": "Pos ini terkunci. Anda tidak akan dapat mengomentari.",
"no_subscriptions_notice": "Anda belum bergabung dengan komunitas mana pun."
"no_subscriptions_notice": "Anda belum bergabung dengan komunitas mana pun.",
"members_count": "{{count}} anggota",
"communities": "komunitas",
"edit": "mengedit",
"moderator": "Moderator"
}

View File

@@ -172,5 +172,9 @@
"no_posts": "nessun post",
"media_url": "URL media",
"post_locked_info": "Questo post è stato bloccato. Non potrai commentarlo.",
"no_subscriptions_notice": "Non ti sei ancora unito a nessuna comunità."
"no_subscriptions_notice": "Non ti sei ancora unito a nessuna comunità.",
"members_count": "{{count}} membri",
"communities": "comunità",
"edit": "modifica",
"moderator": "Moderatore"
}

View File

@@ -172,5 +172,9 @@
"no_posts": "投稿はありません",
"media_url": "メディア URL",
"post_locked_info": "この投稿はロックされています。コメントできません。",
"no_subscriptions_notice": "まだどのコミュニティにも参加していません。"
"no_subscriptions_notice": "まだどのコミュニティにも参加していません。",
"members_count": "{{count}} メンバー",
"communities": "コミュニティ",
"edit": "編集",
"moderator": "モデレーター"
}

View File

@@ -172,5 +172,9 @@
"no_posts": "게시물이 없습니다",
"media_url": "미디어 URL",
"post_locked_info": "이 게시물은 잠겨 있습니다. 댓글을 남길 수 없습니다.",
"no_subscriptions_notice": "아직 어떤 커뮤니티에도 가입하지 않았습니다."
"no_subscriptions_notice": "아직 어떤 커뮤니티에도 가입하지 않았습니다.",
"members_count": "{{count}} 회원",
"communities": "커뮤니티",
"edit": "편집",
"moderator": "모더레이터"
}

View File

@@ -172,5 +172,9 @@
"no_posts": "कोणतेही पोस्ट नाहीत",
"media_url": "मिडिया URL",
"post_locked_info": "हा पोस्ट लॉक झाला आहे. आपण टिप्पणी करू शकणार नाहीत.",
"no_subscriptions_notice": "तुम्ही अद्याप कोणत्याही संघात सामील झालं नाही."
"no_subscriptions_notice": "तुम्ही अद्याप कोणत्याही संघात सामील झालं नाही.",
"members_count": "{{count}} सदस्य",
"communities": "संघा",
"edit": "संपादन",
"moderator": "संचालक"
}

View File

@@ -172,5 +172,9 @@
"no_posts": "geen berichten",
"media_url": "media-url",
"post_locked_info": "Dit bericht is vergrendeld. Je kunt geen opmerkingen plaatsen.",
"no_subscriptions_notice": "Je hebt je nog niet bij een community aangesloten."
"no_subscriptions_notice": "Je hebt je nog niet bij een community aangesloten.",
"members_count": "{{count}} leden",
"communities": "gemeenschap",
"edit": "bewerken",
"moderator": "Moderator"
}

View File

@@ -172,5 +172,9 @@
"no_posts": "ingen innlegg",
"media_url": "medie-URL",
"post_locked_info": "Dette innlegget er låst. Du kan ikke kommentere.",
"no_subscriptions_notice": "Du har ikke blitt med i noen fellesskap ennå."
"no_subscriptions_notice": "Du har ikke blitt med i noen fellesskap ennå.",
"members_count": "{{count}} medlemmer",
"communities": "fellesskap",
"edit": "redigere",
"moderator": "Moderator"
}

View File

@@ -172,5 +172,9 @@
"no_posts": "brak postów",
"media_url": "URL mediów",
"post_locked_info": "Ten post jest zablokowany. Nie będziesz mógł komentować.",
"no_subscriptions_notice": "Nie dołączyłeś jeszcze do żadnej społeczności."
"no_subscriptions_notice": "Nie dołączyłeś jeszcze do żadnej społeczności.",
"members_count": "{{count}} członków",
"communities": "społeczność",
"edit": "edytuj",
"moderator": "Moderator"
}

View File

@@ -172,5 +172,9 @@
"no_posts": "sem publicações",
"media_url": "URL de mídia",
"post_locked_info": "Esta postagem está bloqueada. Você não poderá comentar.",
"no_subscriptions_notice": "Ainda não se juntou a nenhuma comunidade."
"no_subscriptions_notice": "Ainda não se juntou a nenhuma comunidade.",
"members_count": "{{count}} membros",
"communities": "comunidade",
"edit": "editar",
"moderator": "Moderador"
}

View File

@@ -172,5 +172,9 @@
"no_posts": "niciun post",
"media_url": "URL media",
"post_locked_info": "Acest post este blocat. Nu vei putea comenta.",
"no_subscriptions_notice": "Nu te-ai alăturat încă niciunei comunități."
"no_subscriptions_notice": "Nu te-ai alăturat încă niciunei comunități.",
"members_count": "{{count}} membri",
"communities": "comunitate",
"edit": "modifica",
"moderator": "Moderator"
}

View File

@@ -172,5 +172,9 @@
"no_posts": "нет записей",
"media_url": "URL медиа",
"post_locked_info": "Этот пост заблокирован. Вы не сможете оставить комментарий.",
"no_subscriptions_notice": "Вы еще не присоединились ни к одному сообществу."
"no_subscriptions_notice": "Вы еще не присоединились ни к одному сообществу.",
"members_count": "{{count}} участников",
"communities": "сообщество",
"edit": "редактировать",
"moderator": "Модератор"
}

View File

@@ -172,5 +172,9 @@
"no_posts": "asnjë postim",
"media_url": "media url",
"post_locked_info": "Ky post është bllokuar. Nuk do të jeni në gjendje të komentoni.",
"no_subscriptions_notice": "Nuk keni bashkuar akoma ndonjë komunitet."
"no_subscriptions_notice": "Nuk keni bashkuar akoma ndonjë komunitet.",
"members_count": "{{count}} anëtarë",
"communities": "komunitet",
"edit": "modifikohu",
"moderator": "Moderator"
}

View File

@@ -172,5 +172,9 @@
"no_posts": "inga inlägg",
"media_url": "media-url",
"post_locked_info": "Detta inlägg är låst. Du kommer inte att kunna kommentera.",
"no_subscriptions_notice": "Du har ännu inte gått med i någon gemenskap."
"no_subscriptions_notice": "Du har ännu inte gått med i någon gemenskap.",
"members_count": "{{count}} medlemmar",
"communities": "gemenskap",
"edit": "redigera",
"moderator": "Moderator"
}

View File

@@ -172,5 +172,9 @@
"no_posts": "పోస్టులు లేవు",
"media_url": "మీడియా URL",
"post_locked_info": "ఈ పోస్టు లాక్ చేయబడింది. మీరు వ్యాఖ్యానించలేరు.",
"no_subscriptions_notice": "మీరు ఇంకా ఏ కమ్యూనిటీలో చేరలేదు."
"no_subscriptions_notice": "మీరు ఇంకా ఏ కమ్యూనిటీలో చేరలేదు.",
"members_count": "{{count}} సభ్యులు",
"communities": "సమూహం",
"edit": "సమూహం",
"moderator": "మాడరేటర్"
}

View File

@@ -172,5 +172,9 @@
"no_posts": "ไม่มีโพสต์",
"media_url": "URL สื่อ",
"post_locked_info": "โพสต์นี้ถูกล็อก คุณจะไม่สามารถแสดงความคิดเห็นได้",
"no_subscriptions_notice": "คุณยังไม่ได้เข้าร่วมชุมชนใด ๆ"
"no_subscriptions_notice": "คุณยังไม่ได้เข้าร่วมชุมชนใด ๆ",
"members_count": "{{count}} สมาชิก",
"communities": "ชุมชน",
"edit": "แก้ไข",
"moderator": "ผู้ดูแล"
}

View File

@@ -172,5 +172,9 @@
"no_posts": "gönderi yok",
"media_url": "medya URL'si",
"post_locked_info": "Bu gönderi kilitlendi. Yorum yapamayacaksınız.",
"no_subscriptions_notice": "Henüz herhangi bir topluluğa katılmadınız."
"no_subscriptions_notice": "Henüz herhangi bir topluluğa katılmadınız.",
"members_count": "{{count}} üye",
"communities": "topluluk",
"edit": "düzenle",
"moderator": "Moderatör"
}

View File

@@ -172,5 +172,9 @@
"no_posts": "немає повідомлень",
"media_url": "URL медіа",
"post_locked_info": "Цей пост заблокований. Ви не зможете залишити коментар.",
"no_subscriptions_notice": "Ви ще не приєдналися до жодної спільноти."
"no_subscriptions_notice": "Ви ще не приєдналися до жодної спільноти.",
"members_count": "{{count}} учасників",
"communities": "спільнота",
"edit": "редагування",
"moderator": "Модератор"
}

View File

@@ -172,5 +172,9 @@
"no_posts": "کوئی پوسٹ نہیں",
"media_url": "میڈیا یو آر ایل",
"post_locked_info": "یہ پوسٹ بند ہے۔ آپ تبصرہ نہیں کر سکیں گے۔",
"no_subscriptions_notice": "آپ نے ابھی تک کسی بھی کمیونٹی میں شامل نہیں ہوئے۔"
"no_subscriptions_notice": "آپ نے ابھی تک کسی بھی کمیونٹی میں شامل نہیں ہوئے۔",
"members_count": "{{count}} رکن",
"communities": "مجتمع",
"edit": "ترمیم کرنا",
"moderator": "منتظم"
}

View File

@@ -172,5 +172,9 @@
"no_posts": "không có bài viết",
"media_url": "URL phương tiện",
"post_locked_info": "Bài viết này đã bị khóa. Bạn sẽ không thể bình luận.",
"no_subscriptions_notice": "Bạn chưa tham gia vào bất kỳ cộng đồng nào."
"no_subscriptions_notice": "Bạn chưa tham gia vào bất kỳ cộng đồng nào.",
"members_count": "{{count}} thành viên",
"communities": "cộng đồng",
"edit": "sửa đổi",
"moderator": "Quản trị viên"
}

View File

@@ -172,5 +172,9 @@
"no_posts": "没有帖子",
"media_url": "媒体链接",
"post_locked_info": "此帖已锁定。您将无法评论。",
"no_subscriptions_notice": "您尚未加入任何社区。"
"no_subscriptions_notice": "您尚未加入任何社区。",
"members_count": "{{count}} 成员",
"communities": "社区",
"edit": "编辑",
"moderator": "版主"
}

View File

@@ -13,6 +13,7 @@ import Profile from './views/profile';
import Settings from './views/settings';
import Submit from './views/submit';
import Subplebbit from './views/subplebbit';
import SubplebbitSettings from './views/subplebbit/subplebbit-settings';
import Subplebbits from './views/subplebbits';
import AccountBar from './components/account-bar/';
import ChallengeModal from './components/challenge-modal';
@@ -73,9 +74,9 @@ function App() {
<Route path='/profile/comments/:sortType?/:timeFilterName?' element={<Profile />} />
<Route path='/profile/submitted/:sortType?/:timeFilterName?' element={<Profile />} />
<Route path='u/:authorAddress/c/:commentCid?/:sortType?/:timeFilterName?' element={<Author />} />
<Route path='u/:authorAddress/c/:commentCid?/comments/:sortType?/:timeFilterName?' element={<Author />} />
<Route path='u/:authorAddress/c/:commentCid?/submitted/:sortType?/:timeFilterName?' element={<Author />} />
<Route path='/u/:authorAddress/c/:commentCid?/:sortType?/:timeFilterName?' element={<Author />} />
<Route path='/u/:authorAddress/c/:commentCid?/comments/:sortType?/:timeFilterName?' element={<Author />} />
<Route path='/u/:authorAddress/c/:commentCid?/submitted/:sortType?/:timeFilterName?' element={<Author />} />
</Route>
<Route element={pagesLayout}>
<Route path='/submit' element={<Submit />} />
@@ -87,6 +88,7 @@ function App() {
<Route path='/p/:subplebbitAddress/about' element={<About />} />
<Route path='/settings' element={<Settings />} />
<Route path='/p/:subplebbitAddress/settings' element={<SubplebbitSettings />} />
<Route path='/profile/:accountCommentIndex' element={<PendingPost />} />
<Route path='/profile/about' element={<About />} />
@@ -94,11 +96,15 @@ function App() {
<Route path='/u/:authorAddress/c/:commentCid/about' element={<About />} />
<Route path='/inbox' element={<Inbox />} />
<Route path='inbox/unread' element={<Inbox />} />
<Route path='inbox/commentreplies' element={<Inbox />} />
<Route path='inbox/postreplies' element={<Inbox />} />
<Route path='/inbox/unread' element={<Inbox />} />
<Route path='/inbox/commentreplies' element={<Inbox />} />
<Route path='/inbox/postreplies' element={<Inbox />} />
<Route path='/communities' element={<Subplebbits />} />
<Route path='/communities/mine' element={<Subplebbits />} />
<Route path='/communities/mine/subscriber' element={<Subplebbits />} />
<Route path='/communities/mine/contributor' element={<Subplebbits />} />
<Route path='/communities/mine/moderator' element={<Subplebbits />} />
</Route>
</Route>
</Routes>

View File

@@ -16,7 +16,7 @@ import {
} from '@plebbit/plebbit-react-hooks';
// import { getShortAddress } from '@plebbit/plebbit-js';
import styles from './author-sidebar.module.css';
import { getFormattedDuration } from '../../lib/utils/time-utils';
import { getFormattedTimeDuration } from '../../lib/utils/time-utils';
import { isAuthorView, isProfileView } from '../../lib/utils/view-utils';
import {
// findAuthorSubplebbits,
@@ -141,7 +141,7 @@ const AuthorSidebar = () => {
</span>
)}
<span className={styles.age}>
{t('plebbitor_for')} {getFormattedDuration(oldestCommentTimestamp)}
{t('plebbitor_for')} {getFormattedTimeDuration(oldestCommentTimestamp)}
</span>
</div>
</div>

View File

@@ -13,15 +13,16 @@ import {
isDownvotedView,
isHomeView,
isInboxView,
isPostView,
isSettingsView,
isSubplebbitView,
isSubmitView,
isSubplebbitSubmitView,
isPendingView,
isPostView,
isProfileView,
isProfileCommentsView,
isProfileSubmittedView,
isSettingsView,
isSubmitView,
isSubplebbitView,
isSubplebbitSettingsView,
isSubplebbitSubmitView,
isSubplebbitsView,
isUpvotedView,
} from '../../lib/utils/view-utils';
@@ -199,17 +200,17 @@ const SubplebbitsHeaderTabs = () => {
return (
<>
<li>
<Link to={'/communities'} className={styles.selected}>
{t('home')}
<Link to={'/communities'} className={styles.choice} onClick={(e) => e.preventDefault()}>
approved
</Link>
</li>
<li>
<Link to={'/communities'} className={styles.choice}>
<Link to={'/communities'} className={styles.choice} onClick={(e) => e.preventDefault()}>
proposed
</Link>
</li>
<li>
<Link to={'/communities'} className={styles.choice}>
<Link to={'/communities'} className={styles.selected} onClick={(e) => e.preventDefault()}>
{t('my_communities')}
</Link>
</li>
@@ -229,12 +230,13 @@ const HeaderTabs = () => {
const isPostPage = isPostView(location.pathname, params);
const isProfilePage = isProfileView(location.pathname);
const isSubplebbitPage = isSubplebbitView(location.pathname, params);
const isSubplebbitSettingsPage = isSubplebbitSettingsView(location.pathname, params);
const isSubplebbitSubmitPage = isSubplebbitSubmitView(location.pathname, params);
const isSubplebbitsPage = isSubplebbitsView(location.pathname);
if (isPostPage) {
return <CommentsButton />;
} else if (isHomePage || (isSubplebbitPage && !isSubplebbitSubmitPage) || isAllPage) {
} else if (isHomePage || (isSubplebbitPage && !isSubplebbitSubmitPage && !isSubplebbitSettingsPage) || isAllPage) {
return <SortItems />;
} else if ((isProfilePage || isAuthorPage) && !isPendingPage) {
return <AuthorHeaderTabs />;
@@ -261,6 +263,7 @@ const HeaderTitle = ({ title, shortAddress }: { title: string; shortAddress: str
const isSubmitPage = isSubmitView(location.pathname);
const isSubplebbitPage = isSubplebbitView(location.pathname, params);
const isSubplebbitSubmitPage = isSubplebbitSubmitView(location.pathname, params);
const isSubplebbitSettingsPage = isSubplebbitSettingsView(location.pathname, params);
const isSubplebbitsPage = isSubplebbitsView(location.pathname);
const subplebbitTitle = <Link to={`/p/${params.subplebbitAddress}`}>{title || shortAddress}</Link>;
@@ -274,8 +277,14 @@ const HeaderTitle = ({ title, shortAddress }: { title: string; shortAddress: str
{subplebbitTitle}: {submitTitle}
</>
);
} else if (isPostPage || isSubplebbitPage) {
} else if (isPostPage || (isSubplebbitPage && !isSubplebbitSettingsPage)) {
return subplebbitTitle;
} else if (isSubplebbitSettingsPage) {
return (
<>
{subplebbitTitle}: {t('settings')}
</>
);
} else if (isSubmitPage) {
return submitTitle;
} else if (isSettingsPage) {
@@ -287,7 +296,7 @@ const HeaderTitle = ({ title, shortAddress }: { title: string; shortAddress: str
} else if (isInboxPage) {
return t('messages');
} else if (isSubplebbitsPage) {
return 'communities';
return t('communities');
}
return null;
};
@@ -311,16 +320,17 @@ const Header = () => {
const isSubplebbitPage = isSubplebbitView(location.pathname, params);
const isSubmitPage = isSubmitView(location.pathname);
const isSubplebbitSubmitPage = isSubplebbitSubmitView(location.pathname, params);
const isSubplebbitSettingsPage = isSubplebbitSettingsView(location.pathname, params);
const account = useAccount();
const authorComment = useComment({ commentCid: params?.commentCid });
const author = isProfilePage ? account?.author : isAuthorPage ? authorComment?.author : null;
const { imageUrl } = useAuthorAvatar({ author });
const hasFewTabs = isPostPage || isSubmitPage || isSubplebbitSubmitPage || isSettingsPage || isInboxPage;
const hasFewTabs = isPostPage || isSubmitPage || isSubplebbitSubmitPage || isSubplebbitSettingsPage || isSettingsPage || isInboxPage;
const hasStickyHeader =
isHomePage ||
(isSubplebbitPage && !isSubplebbitSubmitPage && !isPostPage && !isAboutPage) ||
(isSubplebbitPage && !isSubplebbitSubmitPage && !isSubplebbitSettingsPage && !isPostPage && !isAboutPage) ||
(isProfilePage && !isAboutPage) ||
isAllPage ||
(isAuthorPage && !isAboutPage);

View File

@@ -17,7 +17,7 @@
.markdown {
background-color: var(--background-markdown);
border: 1px solid var(--grey-light);
border: 1px solid var(--text-primary);
border-radius: 7px;
padding: 5px 10px;
font-weight: 400;

View File

@@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next';
import { getShortAddress } from '@plebbit/plebbit-js';
import { useBlock, Role, useSubplebbitStats, useAccountComment } from '@plebbit/plebbit-react-hooks';
import styles from './sidebar.module.css';
import { getFormattedDate, getFormattedDuration, getFormattedTimeAgo } from '../../lib/utils/time-utils';
import { getFormattedDate, getFormattedTimeDuration, getFormattedTimeAgo } from '../../lib/utils/time-utils';
import { findSubplebbitCreator } from '../../lib/utils/user-utils';
import { isAboutView, isAllView, isHomeView, isPendingView, isPostView, isSubplebbitsView } from '../../lib/utils/view-utils';
import SearchBar from '../search-bar';
@@ -138,7 +138,7 @@ const Sidebar = ({ address, cid, createdAt, description, downvoteCount = 0, role
</Link>
<div className={styles.subscribeContainer}>
<SubscribeButton address={address} />
<span className={styles.subscribers}>{t('readers_count', { count: allActiveUserCount })}</span>
<span className={styles.subscribers}>{t('members_count', { count: allActiveUserCount })}</span>
</div>
<div className={styles.onlineLine}>
<span className={`${styles.onlineIndicator} ${isOnline ? styles.online : styles.offline}`} />
@@ -158,7 +158,7 @@ const Sidebar = ({ address, cid, createdAt, description, downvoteCount = 0, role
<div className={styles.bottom}>
{t('created_by', { creatorAddress: '' })}
<Link to={`/u/${creatorAddress}`} onClick={(e) => e.preventDefault()}>{`u/${creatorAddress}`}</Link>
{createdAt && <span className={styles.age}> {t('community_for', { date: getFormattedDuration(createdAt) })}</span>}
{createdAt && <span className={styles.age}> {t('community_for', { date: getFormattedTimeDuration(createdAt) })}</span>}
<div className={styles.blockSub} onClick={blockConfirm}>
{blocked ? t('unblock_community') : t('block_community')}
</div>

View File

@@ -160,7 +160,7 @@ const TopBar = () => {
))}
</ul>
</div>
<Link to='/communities' className={styles.moreLink}>
<Link to='/communities/mine/moderator' className={styles.moreLink}>
{t('edit')} »
</Link>
</div>

View File

@@ -35,7 +35,7 @@ export const getFormattedTimeAgo = (unixTimestamp: number): string => {
return t('time_x_years_ago', { count: Math.floor(timeDifference / 31104000) });
};
export const getFormattedDuration = (unixTimestamp: number): string => {
export const getFormattedTimeDuration = (unixTimestamp: number): string => {
const currentTime = Date.now() / 1000;
const timeDifference = currentTime - unixTimestamp;
const t = i18next.t;

View File

@@ -102,6 +102,10 @@ export const isSubplebbitView = (pathname: string, params: ParamsType): boolean
return params.subplebbitAddress ? pathname.startsWith(`/p/${params.subplebbitAddress}`) : false;
};
export const isSubplebbitSettingsView = (pathname: string, params: ParamsType): boolean => {
return params.subplebbitAddress ? pathname === `/p/${params.subplebbitAddress}/settings` : false;
};
export const isSubplebbitSubmitView = (pathname: string, params: ParamsType): boolean => {
return params.subplebbitAddress ? pathname === `/p/${params.subplebbitAddress}/submit` : false;
};
@@ -110,6 +114,22 @@ export const isSubplebbitsView = (pathname: string): boolean => {
return pathname.startsWith('/communities');
};
export const isSubplebbitsMineView = (pathname: string): boolean => {
return pathname === '/communities/mine';
};
export const isSubplebbitsMineSubscriberView = (pathname: string): boolean => {
return pathname === '/communities/mine' || pathname === '/communities/mine/subscriber';
};
export const isSubplebbitsMineContributorView = (pathname: string): boolean => {
return pathname === '/communities/mine/contributor';
};
export const isSubplebbitsMineModeratorView = (pathname: string): boolean => {
return pathname === '/communities/mine/moderator';
};
export const isUpvotedView = (pathname: string): boolean => {
return pathname === '/profile/upvoted';
};

View File

@@ -1,4 +1,5 @@
:root .light {
--blue: blue;
--orange: #FF7500;
--green: #228822;
--yellow: goldenrod;
@@ -52,6 +53,7 @@
}
:root .dark {
--blue: rgb(47, 125, 255);
--orange: #FF7500;
--green: #228822;
--yellow: rgb(200, 171, 0);

View File

@@ -9,6 +9,7 @@ const LanguageSettings = () => {
const onSelectLanguage = (e: React.ChangeEvent<HTMLSelectElement>) => {
changeLanguage(e.target.value);
window.location.reload();
};
return (

View File

@@ -0,0 +1 @@
export { default } from './subplebbit-settings';

View File

@@ -0,0 +1,66 @@
.content {
padding: 7px 5px 50px 5px;
color: var(--text);
}
.box {
width: 514px;
background-color: var(--background-primary);
padding: 10px 5px;
font-size: large;
margin-bottom: 10px;
}
.boxTitle {
color: var(--blue);
font-size: 15px;
font-weight: bold;
padding: 0px 10px;
overflow: hidden;
unicode-bidi: isolate;
}
.boxSubtitle {
font-size: 10px;
color: var(--text-info);
padding-left: 10px;
padding-top: 1px;
}
.boxInput {
vertical-align: top;
margin-top: 5px;
padding: 2px 0px 2px 8px;
width: 500px;
}
.boxInput input {
font-size: 100%;
width: 492px;
padding: 3px;
border: 1px solid var(--border-text);
box-shadow: var(--box-shadow-input);
}
.boxInput textarea {
box-shadow: var(--box-shadow-input);
width: 492px;
padding: 3px;
border: 1px solid gray;
height: 100px;
font-family: verdana, arial, helvetica, sans-serif;
line-height: 20px;
font-size: 14px;
}
@media (max-width: 768px) {
.box {
width: 100%;
box-sizing: border-box;
}
.boxInput input, .boxInput textarea {
width: calc(100% - 104px);
box-sizing: border-box;
}
}

View File

@@ -0,0 +1,58 @@
import styles from './subplebbit-settings.module.css';
import { useParams } from 'react-router-dom';
import { useSubplebbit } from '@plebbit/plebbit-react-hooks';
const SubplebbitSettings = () => {
const { subplebbitAddress } = useParams<{ subplebbitAddress: string }>();
const subplebbit = useSubplebbit({ subplebbitAddress });
const { description, rules, suggested, roles, title } = subplebbit || {};
return (
<div className={styles.content}>
<div className={styles.box}>
<div className={styles.boxTitle}>title</div>
<div className={styles.boxSubtitle}>e.g., books: made from trees or pixels. recommendations, news, or thoughts</div>
<div className={styles.boxInput}>
<input type='text' defaultValue={title} />
</div>
</div>
<div className={styles.box}>
<div className={styles.boxTitle}>description</div>
<div className={styles.boxSubtitle}>shown in the sidebar of your community</div>
<div className={styles.boxInput}>
<textarea defaultValue={description} />
</div>
</div>
<div className={styles.box}>
<div className={styles.boxTitle}>logo</div>
<div className={styles.boxSubtitle}>set a community logo using its direct image link (ending in .jpg, .png)</div>
<div className={styles.boxInput}>
<input type='text' defaultValue={suggested?.avatarUrl} />
</div>
</div>
<div className={styles.box}>
<div className={styles.boxTitle}>rules</div>
<div className={styles.boxSubtitle}>shown in the sidebar of your community</div>
<div className={styles.boxInput}>
<textarea defaultValue={rules} autoCorrect='off' autoComplete='off' />
</div>
</div>
<div className={styles.box}>
<div className={styles.boxTitle}>moderators</div>
<div className={styles.boxSubtitle}>let other users moderate and post without challenges</div>
<div className={styles.boxInput}>
<textarea defaultValue={roles} autoCorrect='off' autoComplete='off' />
</div>
</div>
<div className={styles.box}>
<div className={styles.boxTitle}>challenge</div>
<div className={styles.boxSubtitle}>choose a challenge to prevent spam</div>
<div className={styles.boxInput}>
<textarea autoCorrect='off' autoComplete='off' />
</div>
</div>
</div>
);
};
export default SubplebbitSettings;

View File

@@ -1,11 +1,19 @@
@media (max-width: 768px) {
.content {
padding: 7px 0px 0px 0px;
padding: 7px 0px 20px 0px;
}
.sidebar {
display: none;
}
.infobar {
margin: 0px 5px;
}
.subplebbit {
padding-right: 5px;
}
}
@media (min-width: 768px) {
@@ -13,8 +21,8 @@
padding: 7px 5px 0px 5px;
}
.stateString {
max-width: calc(100% - 305px);
.stateString, .infobar {
max-width: calc(100% - 327px);
}
}
@@ -24,7 +32,7 @@
border-style: solid;
border-width: 1px;
font-size: small;
margin: 0 305px 5px 0px;
margin: 3px 0px;
padding: 6px 10px;
color: var(--text);
word-wrap: break-word;
@@ -41,15 +49,51 @@
.subplebbit {
margin-bottom: 10px;
height: auto;
overflow: hidden;
}
.midcol {
margin-right: 5px;
margin-top: 5px;
text-align: right;
width: 12em;
width: 37px;
font-weight: bold;
font-size: small;
float: left;
margin-left: 7px;
padding-right: 7px;
background: transparent;
overflow: hidden;
}
.arrowWrapper {
padding-left: 11px;
padding-top: 2px;
}
.arrowCommon {
width: 15px;
height: 14px;
display: block;
cursor: pointer;
}
.arrowUp {
background-image: url("/public/assets/buttons/arrow-up.png");
}
.upvoted {
background-image: url("/public/assets/buttons/arrow-upvoted.png") !important;
}
.arrowDown {
background-image: url("/public/assets/buttons/arrow-down.png");
}
.downvoted {
background-image: url("/public/assets/buttons/arrow-downvoted.png") !important;
}
.score {
text-align: center;
color: var(--icon);
}
.entry {
@@ -57,24 +101,48 @@
opacity: 1;
}
.onlineIndicator {
background-repeat: no-repeat;
display: inline-flex;
height: 13px;
width: 13px;
margin: 3px 5px -2px 2px;
}
.online {
background-image: url('/public/assets/indicator-online.png');
}
.offline {
background-image: url('/public/assets/indicator-offline.png');
}
.title {
margin-bottom: 1px;
display: inline-flex;
flex-wrap: wrap;
align-items: center;
font-size: medium;
margin-right: 5px;
overflow: hidden;
unicode-bidi: isolate;
margin-bottom: -2px;
}
.title a {
margin-right: 10px;
flex-grow: 1;
color: var(--link);
}
/* TODO: consider to enable this later, when lots of new communities will be proposed */
/* .title a:visited {
color: var(--link-visited);
} */
.subscribeButton {
margin-top: 2px;
}
.description {
font-size: small;
max-width: 60em;
unicode-bidi: isolate;
background-color: var(--background-markdown);
@@ -83,4 +151,53 @@
padding: 2px 5px;
border-radius: 7px;
margin: 5px 0px;
word-wrap: break-word;
font-size: 14px;
}
.subplebbitPreferences {
padding: 0 1px;
line-height: 1.6em;
}
.subplebbitPreferences a {
color: var(--gray-contrast);
font-weight: bold;
}
.subplebbitPreferences a:hover {
text-decoration: underline;
cursor: pointer;
}
.subplebbitsTabs {
border-bottom: 1px dotted gray;
padding: 5px 10px;
margin-left: 5px;
overflow: hidden;
font-size: larger;
display: inline-block;
margin-right: 15px;
text-transform: lowercase;
}
.subplebbitsTabs a span {
display: inline;
white-space: nowrap;
}
.subplebbitsTabs a {
text-decoration: none;
color: var(--text-primary);
}
.separator {
color: var(--gray);
margin: 0px .7ex 0px .7ex;
cursor: default;
}
.selected {
color: var(--green) !important;
font-weight: bold;
}

View File

@@ -1,37 +1,131 @@
import { useMemo } from 'react';
import { Subplebbit as SubplebbitType, useAccountSubplebbits, useSubplebbitStats } from '@plebbit/plebbit-react-hooks';
import { useEffect, useMemo } from 'react';
import { Link, useLocation } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { Subplebbit as SubplebbitType, useAccountSubplebbits, useSubplebbitStats } from '@plebbit/plebbit-react-hooks';
import styles from './subplebbits.module.css';
import Sidebar from '../../components/sidebar';
import SubscribeButton from '../../components/subscribe-button';
import { Link } from 'react-router-dom';
import { getFormattedDuration } from '../../lib/utils/time-utils';
import { getFormattedTimeDuration, getFormattedTimeAgo } from '../../lib/utils/time-utils';
import { isSubplebbitsMineContributorView, isSubplebbitsMineSubscriberView, isSubplebbitsMineModeratorView } from '../../lib/utils/view-utils';
interface SubplebbitProps {
subplebbit: SubplebbitType;
}
const Tabs = () => {
const { t } = useTranslation();
const location = useLocation();
const isSubplebbitsMineSubscriberPage = isSubplebbitsMineSubscriberView(location.pathname);
const isSubplebbitsMineContributorPage = isSubplebbitsMineContributorView(location.pathname);
const isSubplebbitsMineModeratorPage = isSubplebbitsMineModeratorView(location.pathname);
return (
<div className={styles.subplebbitsTabs}>
<Link
to='/communities/mine/subscriber'
className={isSubplebbitsMineSubscriberPage ? styles.selected : styles.choice}
onClick={(e) => e.preventDefault()} // TODO: enable after useSubplebbits cache is implemented in the API
>
subscriber
</Link>
<span className={styles.separator}>|</span>
<Link
to='/communities/mine/contributor'
className={isSubplebbitsMineContributorPage ? styles.selected : styles.choice}
onClick={(e) => e.preventDefault()} // TODO: enable after approving user is implemented in the API
>
approved user
</Link>
<span className={styles.separator}>|</span>
<Link to='/communities/mine/moderator' className={isSubplebbitsMineModeratorPage ? styles.selected : styles.choice}>
{t('moderator')}
</Link>
</div>
);
};
const Infobar = () => {
const { t } = useTranslation();
const location = useLocation();
const isSubplebbitsMineSubscriberPage = isSubplebbitsMineSubscriberView(location.pathname);
const isSubplebbitsMineContributorPage = isSubplebbitsMineContributorView(location.pathname);
const isSubplebbitsMineModeratorPage = isSubplebbitsMineModeratorView(location.pathname);
const infobarText = useMemo(() => {
if (isSubplebbitsMineSubscriberPage) {
return 'below are communities you have subscribed to.';
} else if (isSubplebbitsMineContributorPage) {
return 'below are the communities that you are an approved user on.';
} else if (isSubplebbitsMineModeratorPage) {
return 'below are the communities that you have moderator access to.';
} else {
return (
<>
click the <code>{t('join')}</code> or <code>{t('leave')}</code> buttons to choose which communities appear on the home feed.
</>
);
}
}, [isSubplebbitsMineSubscriberPage, isSubplebbitsMineContributorPage, isSubplebbitsMineModeratorPage, t]);
return <div className={styles.infobar}>{infobarText}</div>;
};
const Subplebbit = ({ subplebbit }: SubplebbitProps) => {
const { t } = useTranslation();
const { address, createdAt, description, shortAddress, title } = subplebbit || {};
const { address, createdAt, description, shortAddress, title, updatedAt } = subplebbit || {};
const { allActiveUserCount } = useSubplebbitStats({ subplebbitAddress: address });
// TODO: make arrows functional when token voting is implemented in the API
const upvoted = false;
const downvoted = false;
const upvoteCount = 0;
const downvoteCount = 0;
const postScore = upvoteCount === 0 && downvoteCount === 0 ? '•' : upvoteCount - downvoteCount || '•';
const isOnline = updatedAt && updatedAt > Date.now() / 1000 - 60 * 30;
const offlineNotice = updatedAt && t('community_last_seen', { dateAgo: getFormattedTimeAgo(updatedAt) });
useEffect(() => {
document.title = `${t('communities')} - seedit`;
}, [t]);
return (
<div className={styles.subplebbit}>
<div className={styles.midcol}>
<SubscribeButton address={address} />
<div className={styles.midcol}>
<div className={styles.arrowWrapper}>
<div className={`${styles.arrowCommon} ${upvoted ? styles.upvoted : styles.arrowUp}`} />
</div>
<div className={styles.score}>{postScore}</div>
<div className={styles.arrowWrapper}>
<div className={`${styles.arrowCommon} ${downvoted ? styles.downvoted : styles.arrowDown}`} />
</div>
</div>
</div>
<div className={styles.entry}>
<div className={styles.title}>
<span className={`${styles.onlineIndicator} ${isOnline ? styles.online : styles.offline}`} />
<Link to={`/p/${address}`}>
p/{address.includes('.') ? address : shortAddress}
{title && `: ${title}`}
</Link>
<span className={styles.subscribeButton}>
<SubscribeButton address={address} />
</span>
</div>
{description && <div className={styles.description}>{description}</div>}
<div className={styles.tagline}>
<span>
{t('readers_count', { count: allActiveUserCount })}, {t('community_for', { date: getFormattedDuration(createdAt) })}
{isOnline ? (
<>
{t('members_count', { count: allActiveUserCount })}, {t('community_for', { date: getFormattedTimeDuration(createdAt) })}
<div className={styles.subplebbitPreferences}>
<Link to={`/p/${address}/settings`}>settings</Link>
</div>
</>
) : (
offlineNotice
)}
</span>
</div>
</div>
@@ -40,7 +134,6 @@ const Subplebbit = ({ subplebbit }: SubplebbitProps) => {
};
const Subplebbits = () => {
const { t } = useTranslation();
const { accountSubplebbits } = useAccountSubplebbits();
const accountSubplebbitsArray = useMemo(() => Object.values(accountSubplebbits), [accountSubplebbits]);
@@ -49,9 +142,8 @@ const Subplebbits = () => {
<div className={`${styles.sidebar}`}>
<Sidebar />
</div>
<div className={styles.infobar}>
click the <code>{t('join')}</code> or <code>{t('leave')}</code> buttons to choose which communities appear on the home feed.
</div>
<Tabs />
<Infobar />
{accountSubplebbitsArray?.map((subplebbit) => <Subplebbit subplebbit={subplebbit} />)}
</div>
);