localize Explore Community
This commit is contained in:
parent
ef0fa23642
commit
f4e94a48cc
7 changed files with 157 additions and 46 deletions
|
|
@ -507,5 +507,52 @@
|
|||
|
||||
"unverified_device": "Unverified Device",
|
||||
"unverified_devices": "Unverified Devices"
|
||||
},
|
||||
|
||||
"Explore": {
|
||||
"explore_community": "Explore Community",
|
||||
|
||||
"add_server": "Add Server",
|
||||
"add_server_desc": "Add server name to explore public communities.",
|
||||
"server_name": "Server Name",
|
||||
"failed_load_public_rooms": "Failed to load public rooms. Please try again.",
|
||||
"view": "View",
|
||||
"featured": "Featured",
|
||||
"servers": "Servers",
|
||||
|
||||
"featured_by_client": "Featured by Client",
|
||||
"featured_by_client_desc": "Public rooms and spaces hand-picked by this client.",
|
||||
"featured_spaces": "Featured Spaces",
|
||||
"featured_rooms": "Featured Rooms",
|
||||
"no_featured": "No featured rooms or spaces yet.",
|
||||
|
||||
"search": "Search",
|
||||
"search_placeholder": "Search for keyword",
|
||||
"clear": "Clear",
|
||||
"enter": "Enter",
|
||||
"protocols": "Protocols",
|
||||
"presets": "Presets",
|
||||
"custom_limit": "Custom Limit",
|
||||
"per_page_limit": "Per Page Item Limit",
|
||||
"change_limit": "Change Limit",
|
||||
"page_limit": "Page Limit: {{limit}}",
|
||||
"results_for": "Results for \"{{term}}\"",
|
||||
"popular_communities": "Popular Communities",
|
||||
"filter_all": "All",
|
||||
"filter_spaces": "Spaces",
|
||||
"filter_rooms": "Rooms",
|
||||
"previous_page": "Previous Page",
|
||||
"next_page": "Next Page",
|
||||
"no_communities": "No communities found!",
|
||||
|
||||
"space_badge": "Space",
|
||||
"members_count": "{{count}} Members",
|
||||
"join": "Join",
|
||||
"joining": "Joining",
|
||||
"retry": "Retry",
|
||||
"join_error": "Join Error",
|
||||
"join_error_unknown": "Failed to join. Unknown Error.",
|
||||
"view_error": "View Error",
|
||||
"cancel": "Cancel"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -509,5 +509,52 @@
|
|||
|
||||
"unverified_device": "Неподтверждённое устройство",
|
||||
"unverified_devices": "Неподтверждённые устройства"
|
||||
},
|
||||
|
||||
"Explore": {
|
||||
"explore_community": "Обзор сообществ",
|
||||
|
||||
"add_server": "Добавить сервер",
|
||||
"add_server_desc": "Укажите имя сервера для обзора публичных сообществ.",
|
||||
"server_name": "Имя сервера",
|
||||
"failed_load_public_rooms": "Не удалось загрузить публичные комнаты. Попробуйте ещё раз.",
|
||||
"view": "Открыть",
|
||||
"featured": "Рекомендуемые",
|
||||
"servers": "Серверы",
|
||||
|
||||
"featured_by_client": "Рекомендации клиента",
|
||||
"featured_by_client_desc": "Подборка публичных комнат и пространств от этого клиента.",
|
||||
"featured_spaces": "Рекомендуемые пространства",
|
||||
"featured_rooms": "Рекомендуемые комнаты",
|
||||
"no_featured": "Рекомендуемых комнат и пространств пока нет.",
|
||||
|
||||
"search": "Поиск",
|
||||
"search_placeholder": "Поиск по ключевому слову",
|
||||
"clear": "Очистить",
|
||||
"enter": "Найти",
|
||||
"protocols": "Протоколы",
|
||||
"presets": "Готовые значения",
|
||||
"custom_limit": "Своё значение",
|
||||
"per_page_limit": "Элементов на странице",
|
||||
"change_limit": "Применить",
|
||||
"page_limit": "На странице: {{limit}}",
|
||||
"results_for": "Результаты для «{{term}}»",
|
||||
"popular_communities": "Популярные сообщества",
|
||||
"filter_all": "Все",
|
||||
"filter_spaces": "Пространства",
|
||||
"filter_rooms": "Комнаты",
|
||||
"previous_page": "Предыдущая",
|
||||
"next_page": "Следующая",
|
||||
"no_communities": "Сообщества не найдены!",
|
||||
|
||||
"space_badge": "Пространство",
|
||||
"members_count": "{{count}} участников",
|
||||
"join": "Присоединиться",
|
||||
"joining": "Вступление…",
|
||||
"retry": "Повторить",
|
||||
"join_error": "Не удалось вступить",
|
||||
"join_error_unknown": "Не удалось присоединиться. Неизвестная ошибка.",
|
||||
"view_error": "Подробности",
|
||||
"cancel": "Отмена"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import {
|
|||
} from 'folds';
|
||||
import classNames from 'classnames';
|
||||
import FocusTrap from 'focus-trap-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import * as css from './style.css';
|
||||
import { RoomAvatar } from '../room-avatar';
|
||||
import { getMxIdLocalPart, mxcUrlToHttp } from '../../utils/matrix';
|
||||
|
|
@ -94,6 +95,7 @@ function ErrorDialog({
|
|||
message: string;
|
||||
children: (openError: () => void) => ReactNode;
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const [viewError, setViewError] = useState(false);
|
||||
const closeError = () => setViewError(false);
|
||||
const openError = () => setViewError(true);
|
||||
|
|
@ -120,7 +122,7 @@ function ErrorDialog({
|
|||
</Text>
|
||||
</Box>
|
||||
<Button size="400" variant="Secondary" fill="Soft" onClick={closeError}>
|
||||
<Text size="B400">Cancel</Text>
|
||||
<Text size="B400">{t('Explore.cancel')}</Text>
|
||||
</Button>
|
||||
</Box>
|
||||
</Dialog>
|
||||
|
|
@ -161,6 +163,7 @@ export const RoomCard = as<'div', RoomCardProps>(
|
|||
},
|
||||
ref
|
||||
) => {
|
||||
const { t } = useTranslation();
|
||||
const mx = useMatrixClient();
|
||||
const useAuthentication = useMediaAuthentication();
|
||||
const joinedRoomId = useJoinedRoomId(allRooms, roomIdOrAlias);
|
||||
|
|
@ -224,7 +227,7 @@ export const RoomCard = as<'div', RoomCardProps>(
|
|||
</Avatar>
|
||||
{(roomType === RoomType.Space || joinedRoom?.isSpaceRoom()) && (
|
||||
<Badge variant="Secondary" fill="Soft" outlined>
|
||||
<Text size="L400">Space</Text>
|
||||
<Text size="L400">{t('Explore.space_badge')}</Text>
|
||||
</Badge>
|
||||
)}
|
||||
</Box>
|
||||
|
|
@ -252,7 +255,7 @@ export const RoomCard = as<'div', RoomCardProps>(
|
|||
{typeof joinedMemberCount === 'number' && (
|
||||
<Box gap="100">
|
||||
<Icon size="50" src={Icons.User} />
|
||||
<Text size="T200">{`${millify(joinedMemberCount)} Members`}</Text>
|
||||
<Text size="T200">{t('Explore.members_count', { count: millify(joinedMemberCount) })}</Text>
|
||||
</Box>
|
||||
)}
|
||||
{typeof joinedRoomId === 'string' && (
|
||||
|
|
@ -263,7 +266,7 @@ export const RoomCard = as<'div', RoomCardProps>(
|
|||
size="300"
|
||||
>
|
||||
<Text size="B300" truncate>
|
||||
View
|
||||
{t('Explore.view')}
|
||||
</Text>
|
||||
</Button>
|
||||
)}
|
||||
|
|
@ -276,7 +279,7 @@ export const RoomCard = as<'div', RoomCardProps>(
|
|||
before={joining && <Spinner size="50" variant="Secondary" fill="Soft" />}
|
||||
>
|
||||
<Text size="B300" truncate>
|
||||
{joining ? 'Joining' : 'Join'}
|
||||
{joining ? t('Explore.joining') : t('Explore.join')}
|
||||
</Text>
|
||||
</Button>
|
||||
)}
|
||||
|
|
@ -290,12 +293,12 @@ export const RoomCard = as<'div', RoomCardProps>(
|
|||
size="300"
|
||||
>
|
||||
<Text size="B300" truncate>
|
||||
Retry
|
||||
{t('Explore.retry')}
|
||||
</Text>
|
||||
</Button>
|
||||
<ErrorDialog
|
||||
title="Join Error"
|
||||
message={joinState.error.message || 'Failed to join. Unknown Error.'}
|
||||
title={t('Explore.join_error')}
|
||||
message={joinState.error.message || t('Explore.join_error_unknown')}
|
||||
>
|
||||
{(openError) => (
|
||||
<Button
|
||||
|
|
@ -307,7 +310,7 @@ export const RoomCard = as<'div', RoomCardProps>(
|
|||
size="300"
|
||||
>
|
||||
<Text size="B300" truncate>
|
||||
View Error
|
||||
{t('Explore.view_error')}
|
||||
</Text>
|
||||
</Button>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import React, { FormEventHandler, useCallback, useRef, useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import FocusTrap from 'focus-trap-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
Avatar,
|
||||
Box,
|
||||
|
|
@ -39,6 +40,7 @@ import { PageNav, PageNavContent, PageNavHeader } from '../../../components/page
|
|||
import { stopPropagation } from '../../../utils/keyboard';
|
||||
|
||||
export function AddServer() {
|
||||
const { t } = useTranslation();
|
||||
const mx = useMatrixClient();
|
||||
const navigate = useNavigate();
|
||||
const [dialog, setDialog] = useState(false);
|
||||
|
|
@ -94,7 +96,7 @@ export function AddServer() {
|
|||
size="500"
|
||||
>
|
||||
<Box grow="Yes">
|
||||
<Text size="H4">Add Server</Text>
|
||||
<Text size="H4">{t('Explore.add_server')}</Text>
|
||||
</Box>
|
||||
<IconButton size="300" onClick={() => setDialog(false)} radii="300">
|
||||
<Icon src={Icons.Cross} />
|
||||
|
|
@ -107,13 +109,13 @@ export function AddServer() {
|
|||
direction="Column"
|
||||
gap="400"
|
||||
>
|
||||
<Text priority="400">Add server name to explore public communities.</Text>
|
||||
<Text priority="400">{t('Explore.add_server_desc')}</Text>
|
||||
<Box direction="Column" gap="100">
|
||||
<Text size="L400">Server Name</Text>
|
||||
<Text size="L400">{t('Explore.server_name')}</Text>
|
||||
<Input ref={serverInputRef} name="serverInput" variant="Background" required />
|
||||
{exploreState.status === AsyncStatus.Error && (
|
||||
<Text style={{ color: color.Critical.Main }} size="T300">
|
||||
Failed to load public rooms. Please try again.
|
||||
{t('Explore.failed_load_public_rooms')}
|
||||
</Text>
|
||||
)}
|
||||
</Box>
|
||||
|
|
@ -132,7 +134,7 @@ export function AddServer() {
|
|||
</Button> */}
|
||||
|
||||
<Button type="submit" onClick={handleView} variant="Secondary" fill="Soft">
|
||||
<Text size="B400">View</Text>
|
||||
<Text size="B400">{t('Explore.view')}</Text>
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
|
|
@ -148,7 +150,7 @@ export function AddServer() {
|
|||
onClick={() => setDialog(true)}
|
||||
>
|
||||
<Text size="B300" truncate>
|
||||
Add Server
|
||||
{t('Explore.add_server')}
|
||||
</Text>
|
||||
</Button>
|
||||
</>
|
||||
|
|
@ -156,6 +158,7 @@ export function AddServer() {
|
|||
}
|
||||
|
||||
export function Explore() {
|
||||
const { t } = useTranslation();
|
||||
const mx = useMatrixClient();
|
||||
useNavToActivePathMapper('explore');
|
||||
const userId = mx.getUserId();
|
||||
|
|
@ -173,7 +176,7 @@ export function Explore() {
|
|||
<Box grow="Yes" gap="300">
|
||||
<Box grow="Yes">
|
||||
<Text size="H4" truncate>
|
||||
Explore Community
|
||||
{t('Explore.explore_community')}
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
|
|
@ -191,7 +194,7 @@ export function Explore() {
|
|||
</Avatar>
|
||||
<Box as="span" grow="Yes">
|
||||
<Text as="span" size="Inherit" truncate>
|
||||
Featured
|
||||
{t('Explore.featured')}
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
|
|
@ -229,7 +232,7 @@ export function Explore() {
|
|||
<NavCategory>
|
||||
<NavCategoryHeader>
|
||||
<Text size="O400" style={{ paddingLeft: config.space.S200 }}>
|
||||
Servers
|
||||
{t('Explore.servers')}
|
||||
</Text>
|
||||
</NavCategoryHeader>
|
||||
{servers.map((server) => (
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import React from 'react';
|
||||
import { Box, Icon, IconButton, Icons, Scroll, Text } from 'folds';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import { useClientConfig } from '../../../hooks/useClientConfig';
|
||||
import { RoomCard, RoomCardGrid } from '../../../components/room-card';
|
||||
|
|
@ -20,6 +21,7 @@ import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize';
|
|||
import { BackRouteHandler } from '../../../components/BackRouteHandler';
|
||||
|
||||
export function FeaturedRooms() {
|
||||
const { t } = useTranslation();
|
||||
const { featuredCommunities } = useClientConfig();
|
||||
const { rooms, spaces } = featuredCommunities ?? {};
|
||||
const allRooms = useAtomValue(allRoomsAtom);
|
||||
|
|
@ -49,14 +51,14 @@ export function FeaturedRooms() {
|
|||
<PageHeroSection>
|
||||
<PageHero
|
||||
icon={<Icon size="600" src={Icons.Bulb} />}
|
||||
title="Featured by Client"
|
||||
subTitle="Find and explore public rooms and spaces featured by client provider."
|
||||
title={t('Explore.featured_by_client')}
|
||||
subTitle={t('Explore.featured_by_client_desc')}
|
||||
/>
|
||||
</PageHeroSection>
|
||||
<Box direction="Column" gap="700">
|
||||
{spaces && spaces.length > 0 && (
|
||||
<Box direction="Column" gap="400">
|
||||
<Text size="H4">Featured Spaces</Text>
|
||||
<Text size="H4">{t('Explore.featured_spaces')}</Text>
|
||||
<RoomCardGrid>
|
||||
{spaces.map((roomIdOrAlias) => (
|
||||
<RoomSummaryLoader key={roomIdOrAlias} roomIdOrAlias={roomIdOrAlias}>
|
||||
|
|
@ -85,7 +87,7 @@ export function FeaturedRooms() {
|
|||
)}
|
||||
{rooms && rooms.length > 0 && (
|
||||
<Box direction="Column" gap="400">
|
||||
<Text size="H4">Featured Rooms</Text>
|
||||
<Text size="H4">{t('Explore.featured_rooms')}</Text>
|
||||
<RoomCardGrid>
|
||||
{rooms.map((roomIdOrAlias) => (
|
||||
<RoomSummaryLoader key={roomIdOrAlias} roomIdOrAlias={roomIdOrAlias}>
|
||||
|
|
@ -123,7 +125,7 @@ export function FeaturedRooms() {
|
|||
>
|
||||
<Icon size="400" src={Icons.Info} />
|
||||
<Text size="T300" align="Center">
|
||||
No rooms or spaces featured by client provider.
|
||||
{t('Explore.no_featured')}
|
||||
</Text>
|
||||
</Box>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import {
|
|||
} from 'folds';
|
||||
import { useNavigate, useParams, useSearchParams } from 'react-router-dom';
|
||||
import FocusTrap from 'focus-trap-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { MatrixClient, Method, RoomType } from 'matrix-js-sdk';
|
||||
|
|
@ -62,24 +63,26 @@ type RoomTypeFilter = {
|
|||
title: string;
|
||||
value: string | undefined;
|
||||
};
|
||||
const useRoomTypeFilters = (): RoomTypeFilter[] =>
|
||||
useMemo(
|
||||
const useRoomTypeFilters = (): RoomTypeFilter[] => {
|
||||
const { t } = useTranslation();
|
||||
return useMemo(
|
||||
() => [
|
||||
{
|
||||
title: 'All',
|
||||
title: t('Explore.filter_all'),
|
||||
value: undefined,
|
||||
},
|
||||
{
|
||||
title: 'Spaces',
|
||||
title: t('Explore.filter_spaces'),
|
||||
value: RoomType.Space,
|
||||
},
|
||||
{
|
||||
title: 'Rooms',
|
||||
title: t('Explore.filter_rooms'),
|
||||
value: 'null',
|
||||
},
|
||||
],
|
||||
[]
|
||||
[t]
|
||||
);
|
||||
};
|
||||
|
||||
const FALLBACK_ROOMS_LIMIT = 24;
|
||||
|
||||
|
|
@ -91,6 +94,7 @@ type SearchProps = {
|
|||
onReset: () => void;
|
||||
};
|
||||
function Search({ active, loading, searchInputRef, onSearch, onReset }: SearchProps) {
|
||||
const { t } = useTranslation();
|
||||
const handleSearchSubmit: FormEventHandler<HTMLFormElement> = (evt) => {
|
||||
evt.preventDefault();
|
||||
const { searchInput } = evt.target as HTMLFormElement & {
|
||||
|
|
@ -106,14 +110,14 @@ function Search({ active, loading, searchInputRef, onSearch, onReset }: SearchPr
|
|||
return (
|
||||
<Box as="form" direction="Column" gap="100" onSubmit={handleSearchSubmit}>
|
||||
<span data-spacing-node />
|
||||
<Text size="L400">Search</Text>
|
||||
<Text size="L400">{t('Explore.search')}</Text>
|
||||
<Input
|
||||
ref={searchInputRef}
|
||||
style={{ paddingRight: config.space.S300 }}
|
||||
name="searchInput"
|
||||
size="500"
|
||||
variant="Background"
|
||||
placeholder="Search for keyword"
|
||||
placeholder={t('Explore.search_placeholder')}
|
||||
before={
|
||||
active && loading ? (
|
||||
<Spinner variant="Secondary" size="200" />
|
||||
|
|
@ -132,11 +136,11 @@ function Search({ active, loading, searchInputRef, onSearch, onReset }: SearchPr
|
|||
after={<Icon size="50" src={Icons.Cross} />}
|
||||
onClick={onReset}
|
||||
>
|
||||
<Text size="B300">Clear</Text>
|
||||
<Text size="B300">{t('Explore.clear')}</Text>
|
||||
</Chip>
|
||||
) : (
|
||||
<Chip type="submit" variant="Primary" size="400" radii="Pill" outlined>
|
||||
<Text size="B300">Enter</Text>
|
||||
<Text size="B300">{t('Explore.enter')}</Text>
|
||||
</Chip>
|
||||
)
|
||||
}
|
||||
|
|
@ -153,6 +157,7 @@ function ThirdPartyProtocolsSelector({
|
|||
instanceId?: string;
|
||||
onChange: (instanceId?: string) => void;
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const mx = useMatrixClient();
|
||||
const [menuAnchor, setMenuAnchor] = useState<RectCords>();
|
||||
|
||||
|
|
@ -196,7 +201,7 @@ function ThirdPartyProtocolsSelector({
|
|||
style={{ padding: config.space.S100, minWidth: toRem(100) }}
|
||||
>
|
||||
<Text style={{ padding: config.space.S100 }} size="L400" truncate>
|
||||
Protocols
|
||||
{t('Explore.protocols')}
|
||||
</Text>
|
||||
<Box direction="Column">
|
||||
<MenuItem
|
||||
|
|
@ -252,6 +257,7 @@ type LimitButtonProps = {
|
|||
onLimitChange: (limit: string) => void;
|
||||
};
|
||||
function LimitButton({ limit, onLimitChange }: LimitButtonProps) {
|
||||
const { t } = useTranslation();
|
||||
const [menuAnchor, setMenuAnchor] = useState<RectCords>();
|
||||
|
||||
const handleLimitSubmit: FormEventHandler<HTMLFormElement> = (evt) => {
|
||||
|
|
@ -288,7 +294,7 @@ function LimitButton({ limit, onLimitChange }: LimitButtonProps) {
|
|||
<Menu variant="Surface">
|
||||
<Box direction="Column" gap="400" style={{ padding: config.space.S300 }}>
|
||||
<Box direction="Column" gap="100">
|
||||
<Text size="L400">Presets</Text>
|
||||
<Text size="L400">{t('Explore.presets')}</Text>
|
||||
<Box gap="100" wrap="Wrap">
|
||||
<Chip variant="SurfaceVariant" onClick={() => setLimit('24')} radii="Pill">
|
||||
<Text size="T200">24</Text>
|
||||
|
|
@ -303,7 +309,7 @@ function LimitButton({ limit, onLimitChange }: LimitButtonProps) {
|
|||
</Box>
|
||||
<Box as="form" onSubmit={handleLimitSubmit} direction="Column" gap="300">
|
||||
<Box direction="Column" gap="100">
|
||||
<Text size="L400">Custom Limit</Text>
|
||||
<Text size="L400">{t('Explore.custom_limit')}</Text>
|
||||
<Input
|
||||
name="limitInput"
|
||||
size="300"
|
||||
|
|
@ -314,11 +320,11 @@ function LimitButton({ limit, onLimitChange }: LimitButtonProps) {
|
|||
outlined
|
||||
type="number"
|
||||
radii="400"
|
||||
aria-label="Per Page Item Limit"
|
||||
aria-label={t('Explore.per_page_limit')}
|
||||
/>
|
||||
</Box>
|
||||
<Button type="submit" size="300" variant="Primary" radii="400">
|
||||
<Text size="B300">Change Limit</Text>
|
||||
<Text size="B300">{t('Explore.change_limit')}</Text>
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
|
|
@ -334,13 +340,14 @@ function LimitButton({ limit, onLimitChange }: LimitButtonProps) {
|
|||
variant="SurfaceVariant"
|
||||
after={<Icon size="100" src={Icons.ChevronBottom} />}
|
||||
>
|
||||
<Text size="T200" truncate>{`Page Limit: ${limit}`}</Text>
|
||||
<Text size="T200" truncate>{t('Explore.page_limit', { limit })}</Text>
|
||||
</Chip>
|
||||
</PopOut>
|
||||
);
|
||||
}
|
||||
|
||||
export function PublicRooms() {
|
||||
const { t } = useTranslation();
|
||||
const { server } = useParams();
|
||||
const mx = useMatrixClient();
|
||||
const userId = mx.getUserId();
|
||||
|
|
@ -488,7 +495,7 @@ export function PublicRooms() {
|
|||
<Box grow="No" justifyContent="Center" alignItems="Center" gap="200">
|
||||
{screenSize !== ScreenSize.Mobile && <Icon size="400" src={Icons.Search} />}
|
||||
<Text size="H3" truncate>
|
||||
Search
|
||||
{t('Explore.search')}
|
||||
</Text>
|
||||
</Box>
|
||||
<Box grow="Yes" basis="No" />
|
||||
|
|
@ -532,9 +539,9 @@ export function PublicRooms() {
|
|||
<Box direction="Column" gap="400">
|
||||
<Box direction="Column" gap="300">
|
||||
{isSearch ? (
|
||||
<Text size="H4">{`Results for "${serverSearchParams.term}"`}</Text>
|
||||
<Text size="H4">{t('Explore.results_for', { term: serverSearchParams.term })}</Text>
|
||||
) : (
|
||||
<Text size="H4">Popular Communities</Text>
|
||||
<Text size="H4">{t('Explore.popular_communities')}</Text>
|
||||
)}
|
||||
<Box gap="200">
|
||||
{roomTypeFilters.map((filter) => (
|
||||
|
|
@ -624,7 +631,7 @@ export function PublicRooms() {
|
|||
disabled={!data.prev_batch}
|
||||
>
|
||||
<Text size="B300" truncate>
|
||||
Previous Page
|
||||
{t('Explore.previous_page')}
|
||||
</Text>
|
||||
</Button>
|
||||
<Box data-spacing-node grow="Yes" />
|
||||
|
|
@ -635,7 +642,7 @@ export function PublicRooms() {
|
|||
disabled={!data.next_batch}
|
||||
>
|
||||
<Text size="B300" truncate>
|
||||
Next Page
|
||||
{t('Explore.next_page')}
|
||||
</Text>
|
||||
</Button>
|
||||
</Box>
|
||||
|
|
@ -651,7 +658,7 @@ export function PublicRooms() {
|
|||
>
|
||||
<Icon size="400" src={Icons.Info} />
|
||||
<Text size="T300" align="Center">
|
||||
No communities found!
|
||||
{t('Explore.no_communities')}
|
||||
</Text>
|
||||
</Box>
|
||||
))}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import React from 'react';
|
||||
import { Icon, Icons } from 'folds';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import { SidebarAvatar, SidebarItem, SidebarItemTooltip } from '../../../components/sidebar';
|
||||
import { useExploreSelected } from '../../../hooks/router/useExploreSelected';
|
||||
|
|
@ -17,6 +18,7 @@ import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize';
|
|||
import { useNavToActivePathAtom } from '../../../state/hooks/navToActivePath';
|
||||
|
||||
export function ExploreTab() {
|
||||
const { t } = useTranslation();
|
||||
const mx = useMatrixClient();
|
||||
const screenSize = useScreenSizeContext();
|
||||
const clientConfig = useClientConfig();
|
||||
|
|
@ -52,7 +54,7 @@ export function ExploreTab() {
|
|||
|
||||
return (
|
||||
<SidebarItem active={exploreSelected}>
|
||||
<SidebarItemTooltip tooltip="Explore Community">
|
||||
<SidebarItemTooltip tooltip={t('Explore.explore_community')}>
|
||||
{(triggerRef) => (
|
||||
<SidebarAvatar as="button" ref={triggerRef} outlined onClick={handleExploreClick}>
|
||||
<Icon src={Icons.Explore} filled={exploreSelected} />
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue